10

I'm trying to so sort an array by 2 fields. I have a boolean: isFavorite and a string: name. All the booleans who are true have to be the first items. But I want the array to be alphabetic. This is my code so far (tried multiple things):

data.sort(function (x,y) {
    if (x.isFavorite){
        return -1;
    }
    if (x.isFavorite && !y.isFavorite && (x.name < y.name)){
        return -1;
    }  else if ((x.isFavorite === y.isFavorite) && (x.name === y.name)){
        return 0;
    } else if (x.isFavorite && y.isFavorite && (x.name < y.name)){
        return -1;
    } else if (!x.isFavorite && !y.isFavorite && (x.name > y.name)){
        return 1;
    }
}
1

5 Answers 5

16

Why so much conditions and overlapping ?

Just use logical OR operator in order to sort array by two fields.

Also, I used + (Boolean) in order to force converting to Number.

grouperArray.sort((a, b) => (+a.isFavorite) - (+b.isFavorite) || a.name.localeCompare(b.name));

let data = [{ isFavorite:false, name:'A' }, { isFavorite:true, name:'C' }, { isFavorite:true, name:'B' }];
data.sort((a,b) => (+b.isFavorite) - (+a.isFavorite) || a.name.localeCompare(b.name));
console.log(data);

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

Comments

3

const data = [
  {isFavorite: false, name: 'b'},
  {isFavorite: false, name: 'f'},
  {isFavorite: true, name: 'c'},
  {isFavorite: true, name: 'a'},
  {isFavorite: false, name: 'd'},
  {isFavorite: true, name: 'g'}
];

const sortedData = data.sort((a, b) => {
  if (a.isFavorite !== b.isFavorite) {
    return a.isFavorite ? -1 : 1;
  } else {
    return a.name > b.name ? 1 : -1;
  }
});
  
console.log(sortedData);

Comments

3

Try this one:

const data = [
  {isFavorite: false, name: 'B'}, 
  {isFavorite: false, name: 'A'}, 
  {isFavorite: true, name: 'C'}, 
  {isFavorite: true, name: 'D'},
  {isFavorite: true, name: 'A'},
  {isFavorite: false, name: 'A'},
  {isFavorite: false, name: 'D'},
  {isFavorite: true, name: 'Z'},
];

const compareLoc = (a, b) => a.name.localeCompare(b.name)
const result = [...data.filter(d => d.isFavorite).sort(compareLoc),
...data.filter(d => !d.isFavorite).sort(compareLoc)];
console.log(result);

Following snippet works.

const data = [
  {isFavorite: false, name: 'B'}, 
  {isFavorite: false, name: 'A'}, 
  {isFavorite: true, name: 'C'}, 
  {isFavorite: true, name: 'D'},
  {isFavorite: true, name: 'A'},
  {isFavorite: false, name: 'A'},
  {isFavorite: false, name: 'D'},
  {isFavorite: true, name: 'Z'},
];

data.sort(function (x, y) {
    // if both are true or false, we should compare name attributes
    if (x.isFavorite === y.isFavorite) {
        return x.name.localeCompare(y.name);
    } return x.isFavorite ? -1 : 1
}
)
console.log(data)

9 Comments

This almost works for me, the strange thing is that everything works fine except at the bottom of my dropdown (array), I have a few items that didn't get sorted like this: a-z, a, c, f, g , w => so the first part is perfectly fine, but after Z comes like 10 items that starts again from "a"
That's not weird, he doesn't sort the end of the array. You're supposed to sort every case of a condition, and he only does it in the if statement. Copy/paste the code of the if in the else, and below it, and it should work
Can you post the snippet for clarification? I did what I think you meant but doesn't work
I didn't get the exact point, don't you need isFavorite(a-z) then !isFavorite(a-z)? Why a-z comes after a-z is I order isFavorite = true ones before false ones in all scenarios
can you check the upper snippet I just shared
|
0

You problem is that first two if's are overlapping and second if is not reachable if x.isFavorite is true then first if will return.

Also, you are not checking some scenarios like y.isFavorite is true and x.isFavorite is not.

You can write it as

if ( x.isFavorite != y.isFavorite )
{
   return x.isFavorite ? -1 : 1;
}
else
{
   return x.name.localeCompare( y.name );
}

Comments

0

Here you go :)

var arr = [
  {
    isFavorite: false,
    name: 'a'
  },
  {
    isFavorite: true,
    name: 'b'
  },
  {
    isFavorite: true,
    name: 'c'
  },
  {
    isFavorite: false,
    name: 'c'
  }
];

arr.sort(function (x,y) {
    if (x.isFavorite > y.isFavorite){
        return -1;
    }else if(x.isFavorite == y.isFavorite){
        return x.name > y.name;
    }else{
        return 1;
    }
});

console.log(arr);

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.