RFFD
RFFD

Reputation: 5

Javascript how to sort by dynamic property

I have the following array, and I want to sort it following these rules

  1. Primary true and shouldPrioritize true
  2. Primary true and shouldPrioritize false
  3. Primary false and shouldPrioritize true
  4. Primary false and shouldPrioritize false
const array = [{
  primary: true
  shouldPrioritize: false,
},
{
  primary: true
  shouldPrioritize: true,
}
{
  primary: false
  shouldPrioritize: true,
}
{
  primary: false
  shouldPrioritize: false,
}
]

What's the easiest way of using sort to match the rules? If we remove one of the items we should sort accordingly too.

Upvotes: 0

Views: 42

Answers (2)

Lennholm
Lennholm

Reputation: 7460

The easiest way to sort is to use the array's native sort() method. It takes a function that compares two items in the array and returns a number. If the function returns a negative number, the first item is placed before the second item but if it returns a positive number they get reversed.

In your case, you can do this by considering your boolean values as numbers. In JS, booleans can be implicitly coerced into numbers, true to 1 and false to 0. According to your rules, the primary property has a higher precedent than shouldPrioritize, so lets's increase its value by one. Then it's only a matter of sorting by the principle put higher values first.

Your solution can then look like this:

const array = [{ primary: true, shouldPrioritize: false }, { primary: true, shouldPrioritize: true }, { primary: false, shouldPrioritize: true }, { primary: false, shouldPrioritize: false }];

array.sort((a, b) => (b.primary * 2 + b.shouldPrioritize) - (a.primary * 2 + a.shouldPrioritize));

console.log(array);

Upvotes: 0

Nina Scholz
Nina Scholz

Reputation: 386550

Just take the deltas of the booleans.

const
    array = [{ primary: true, shouldPrioritize: false }, { primary: true, shouldPrioritize: true }, { primary: false, shouldPrioritize: true }, { primary: false, shouldPrioritize: false }];
    
array.sort((a, b) => b.primary - a.primary || b.shouldPrioritize - a.shouldPrioritize);

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

Upvotes: 2

Related Questions