Reputation: 865
In my function, I have this code to retrieve a list of objects:
this.personService.getAccountOverview().subscribe(persons => this.personsSubject.next(persons));
The output will be something like this:
[
{ name: 'John Doe', age: 44, isCrazy: false, isAnotherLevelCrazy: false, isExtremeCrazy: false },
{ name: 'Jane Doe', age: 28, isCrazy: false, isAnotherLevelCrazy: false, isExtremeCrazy: false },
{ name: 'Crazy Doe', age: 36, isCrazy: true, isAnotherLevelCrazy: false, isExtremeCrazy: false },
{ name: 'Extreme Doe', age: 23, isCrazy: false, isAnotherLevelCrazy: true, isExtremeCrazy: true }
]
What I try to achieve is if any of 3 crazy properties is set to true put this object on top of the list. There can be more objects where this is true than place those sorted by name on top of the list.
below the crazy people will be the "non" crazy people also sorted by name. It should be ordered like this:
crazy doe, extreme doe, jane doe and then john doe.
I tried this but I do not get the right results / no sorting (also I did not start on the name sorting for the top items yet):
this.personService.getAccountOverview().subscribe(persons => {
persons.sort((a,b) => {
if(b.isCrazy || b.isAnotherLevelCrazy || extremeCrazy) {
return 1;
}
});
this.personsSubject.next(persons)
});
It look a lot but the main question is How can you sort the list based on one property and use a "then" or something else to sort the list again. Sort the list with a primary value and a secondary value
Can anyone help me with this?
My solution:
const isCrazyHuman = c => c.isCrazy || c.isAnotherLevelCrazy || c.isExtremeCrazy;
const result = persons.sort((a, b) => {
const aCrazy = isCrazyHuman(a);
const bCrazy = isCrazyHuman(b);
if(!aCrazy && !bCrazy || aCrazy && bCrazy) {
return a.name.localeCompare(b.name);
} else if (aCrazy) {
return -1
} else {
return 1;
}
});
Thank you Mureinik. I could't answer this question because of the closed status. So I updated the question
Upvotes: -2
Views: 43
Reputation: 312076
Your implementation checks only the properties of b
, which is incorrect - if a
were also crazy, b
would not necessarily be "greater" than a
.
The correct logic, as you described it, should be as follows:
a
is crazy but b
is not, a
should come firstb
is crazy but a
is not, b
should come firsta
and b
are equally crazy, sort them by their names.Translated to code, it would look like this:
const isCarzy = p => p.isCrazy || p.isAnotherLevelCrazy || p.isExtremeCrazy;
persons.sort((a, b) => {
const aCrazy = isCarzy(a);
const bCrazy = isCarzy(b);
if (aCrazy) {
if (!bCrazy) {
return -1;
}
} else {
if (bCrazy) {
return 1;
}
}
return a.name.localeCompare(b.name);
});
Upvotes: 1