Home > Net >  Sort an array of objects by two properties, but force one to go first
Sort an array of objects by two properties, but force one to go first

Time:10-09

I have an array of objects like this:

// dishes: [
   {category: 'LEGUME', description: 'A'},
   {category: 'VEGETABLE', description: 'B'},
   {category: 'FISH', description: 'C'},
   {category: 'LEGUME', description: 'E'},
   {category: 'LEGUME', description: 'B'},
   {category: 'LEGUME', description: 'N'},
]

I'm sorting this array with this function:

const dishes = dishes.sort((a, b) => {
            if (a.category > b.category) return -1;
            if (a.category < b.category) return 1;
            return a.description.localeCompare(b.description);
          });

The output from above is like this:

// dishes: [
   {category: 'LEGUME', description: 'A'},
   {category: 'LEGUME', description: 'B'},
   {category: 'LEGUME', description: 'E'},
   {category: 'LEGUME', description: 'N'},
   {category: 'VEGETABLE', description: 'B'},
   {category: 'FISH', description: 'C'},
]

But now I want to force one of the categories to be the first one, let's say VEGETABLE, so the output should be:

// dishes: [
   {category: 'VEGETABLE', description: 'B'},
   {category: 'LEGUME', description: 'A'},
   {category: 'LEGUME', description: 'B'},
   {category: 'LEGUME', description: 'E'},
   {category: 'LEGUME', description: 'N'},
   {category: 'FISH', description: 'C'},
]

I've tried a bunch of solutions from other questions but none worked, any suggestions? is it possible?

Thanks in advance.

CodePudding user response:

First compare by the difference of whether the items are of VEGETABLE or not - proceed to the rest of the sort function only if that results in 0.

const dishes = [
   {category: 'LEGUME', description: 'A'},
   {category: 'VEGETABLE', description: 'B'},
   {category: 'FISH', description: 'C'},
   {category: 'LEGUME', description: 'E'},
   {category: 'LEGUME', description: 'B'},
   {category: 'LEGUME', description: 'N'},
];
dishes.sort((a, b) => {
  const vegResult = a.category === 'VEGETABLE' - b.category === 'VEGETABLE';
  if (vegResult) return vegResult;
  if (a.category > b.category) return -1;
  if (a.category < b.category) return 1;
  return a.description.localeCompare(b.description);
});
console.log(dishes);

CodePudding user response:

let dishes = [
   {category: 'LEGUME', description: 'A'},
   {category: 'VEGETABLE', description: 'B'},
   {category: 'FISH', description: 'C'},
   {category: 'LEGUME', description: 'E'},
   {category: 'LEGUME', description: 'B'},
   {category: 'LEGUME', description: 'N'},
]

const data = dishes.sort((a, b) => {
            if(a.category=='VEGETABLE'){
              return -1;
            }
            if (a.category > b.category) return -1;
            if (a.category < b.category) return 1;
            return a.description.localeCompare(b.description);
          });
          
console.log(data)

CodePudding user response:

You can special case the VEGETABLE value in your sort function:

const dishes = [
   {category: 'LEGUME', description: 'A'},
   {category: 'VEGETABLE', description: 'B'},
   {category: 'FISH', description: 'C'},
   {category: 'LEGUME', description: 'E'},
   {category: 'LEGUME', description: 'B'},
   {category: 'LEGUME', description: 'N'}
]

dishes.sort((a, b) => {
  if (a.category == 'VEGETABLE') return -1
  if (b.category == 'VEGETABLE') return 1
  res = a.category.localeCompare(b.category)
  if (res) return res
  return a.description.localeCompare(b.description);
});

console.log(dishes)
.as-console-wrapper { max-height:100% !important; top 0; }

Note that sort sorts the array inplace so you don't need to assign the result from it.

  • Related