1

I'd like to sort this JavaScript array by three values, but I can't seem to figure out how to sort by more than one property at a time.

The requirements are:

  1. featured items should be at the very top
  2. Then items with no name (null)
  3. Then items with a name that are not featured
  4. Sort everything by createdAt in descending order (newest first)

This is the array:

var items [
    { name: 'foo-1', featured: true,  createdAt: 1493000001 },
    { name: null,    featured: false, createdAt: 1493000003 },
    { name: 'foo-3', featured: true,  createdAt: 1493000002 },
    { name: 'foo-4', featured: false, createdAt: 1493000004 },
    { name: 'foo-5', featured: false, createdAt: 1493000005 },
];

The result should be:

[
    { name: 'foo-3', featured: true,  createdAt: 1493000002 },
    { name: 'foo-1', featured: true,  createdAt: 1493000001 },
    { name: null,    featured: false, createdAt: 1493000003 },
    { name: 'foo-5', featured: false, createdAt: 1493000005 },
    { name: 'foo-4', featured: false, createdAt: 1493000004 },
]
4

2 Answers 2

6

var items = [
    { name: 'foo-1', featured: true,  createdAt: 1493000001 },
    { name: null,    featured: false, createdAt: 1493000003 },
    { name: 'foo-3', featured: true,  createdAt: 1493000002 },
    { name: 'foo-4', featured: false, createdAt: 1493000004 },
    { name: 'foo-5', featured: false, createdAt: 1493000005 },
];

items.sort(function(a, b) {
    if(a.featured && !b.featured) return -1; // if a is featured and b is not, then put a above b
    if(!a.featured && b.featured) return 1;  // if b is featured and a is not, then put b above a
    
    if(!a.name && b.name) return -1;         // if a doesn't have a name and b does, then put a above b
    if(a.name && !b.name) return 1;          // if b doesn't have a name and a does, then put b above a
    
    return b.createdAt - a.createdAt;        // otherwise (a and b have simillar properties), then sort by createdAt descendently
});

console.log(items);

Sign up to request clarification or add additional context in comments.

Comments

1

You can use a compare function which can be passed as an argument to the sort() function - see Array.prototype.sort() for more detailed information. In your case the compare function may look like this:

var items = [
    { name: 'foo-1', featured: true,  createdAt: 1493000001 },
    { name: null,    featured: false, createdAt: 1493000003 },
    { name: 'foo-3', featured: true,  createdAt: 1493000002 },
    { name: 'foo-4', featured: false, createdAt: 1493000004 },
    { name: 'foo-5', featured: false, createdAt: 1493000005 },
];

function compare(a, b) {
    if (a.featured === true && b.featured === false) return -1;
    if (a.featured === false && b.featured === true) return 1;
    if (a.name === null && b.featured !== null) return -1;
    if (a.name !== null && b.name === null) return 1;

    return b.createdAt - a.createdAt;
};

items.sort(compare);

It should cover the case when the name is an empty string.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.