Reputation: 3543
I want to sort this array of objects where each object should be ascending in each unit
and units should be sorted ascending based on order
too:
const userCards = [
{
unit: 5,
order: 1,
},
{
unit: 5,
order: 3,
},
{
unit: 5,
order: 2,
},
{
unit: 6,
order: 2,
},
{
unit: 6,
order: 1,
},
{
unit: 6,
order: 3,
},
{
unit: 7,
order: 1,
},
{
unit: 4,
order: 2,
},
{
unit: 1,
order: 1,
},
{
unit: 1,
order: 2,
},
{
unit: 1,
order: 3,
},
{
unit: 1,
order: 4,
},
{
unit: 3,
order: 2,
}
]
function compare(a, b) {
if (a.unit > b.unit && a.order > b.order) return 1;
if (a.unit < b.unit) return -1;
return 0;
}
const res = userCards.sort(compare);
console.log(res)
For instance the desired result would be :
{
unit: 5,
order: 1,
},
{
unit: 5,
order: 2,
},
{
unit: 6,
order: 1,
},
{
unit: 6,
order: 2,
},
As you see so far this is not happening!
How can I fix this?
Upvotes: 1
Views: 77
Reputation: 3829
A | B | a.unit > b.unit && a.order > b.order | a.unit > b.unit | value returned |
---|---|---|---|---|
{unit: 5, order: 3} | {unit: 4, order: 1} | True | 1 <-- meaning A > B | |
{unit: 5, order: 3} | {unit: 5, order: 1} | False | False | 0 <-- meaning same value |
{unit: 4, order: 1} | {unit: 3, order: 2} | False | True | -1 <-- meaning A > B |
{unit: 1, order: 1} | {unit: 3, order: 2} | False | True | 0 <-- meaning same value |
As you can see on this example, your condition does not work as you want since it has return 0
2 times.
Reading the Array#sort documentation the return of the sort function is the following
compareFunction(a, b) return value | sort order |
---|---|
> 0 | sort b before a |
< 0 | sort a before b |
=== 0 | keep original order of a and b |
So here you can just do the following :
function compare(a, b) {
if(a.unit === b.unit) return a.order - b.order
else return a.unit - b.unit
}
Or with one line using ternary
function compare = (a, b) => a.unit === b.unit ? a.order - b.order : a.unit - b.unit
const userCards = [
{
unit: 5,
order: 1,
},
{
unit: 5,
order: 3,
},
{
unit: 5,
order: 2,
},
{
unit: 6,
order: 2,
},
{
unit: 6,
order: 1,
},
{
unit: 6,
order: 3,
},
{
unit: 7,
order: 1,
},
{
unit: 4,
order: 2,
},
{
unit: 1,
order: 1,
},
{
unit: 1,
order: 2,
},
{
unit: 1,
order: 3,
},
{
unit: 1,
order: 4,
},
{
unit: 3,
order: 2,
}
]
const compare = (a, b) => a.unit === b.unit ? a.order - b.order : a.unit - b.unit
const res = userCards.sort(compare);
console.log(JSON.stringify(res))
Upvotes: 0
Reputation: 43853
Details are commented in example below
const userCards = [{
unit: 5,
order: 1,
},
{
unit: 5,
order: 2,
},
{
unit: 6,
order: 2,
},
{
unit: 6,
order: 1,
},
{
unit: 6,
order: 3,
},
{
unit: 7,
order: 1,
},
{
unit: 5,
order: 3,
},
{
unit: 4,
order: 2,
},
{
unit: 1,
order: 1,
},
{
unit: 1,
order: 2,
},
{
unit: 1,
order: 3,
},
{
unit: 1,
order: 4,
},
{
unit: 3,
order: 2,
}
];
/*
Create a reference object array that stores the keys needed to be in order
*/
let orderKey = [{
key: 'unit'
}, {
key: 'order'
}];
// Pass both object arrays
function compare(objArray, sortOrder) {
// Start with .sort()
return objArray.sort((a, b) => {
// Define counter and ternary value initial defaults
let i = 0,
result = 0;
/*
As long as counter is less than sortOrder total AND ternary is 0
...Define A as previous value of current key...
...Define B as current value of current key...
...If A is less than B return -1 (A and B stay)...
...if A is greater than B return 1 (A and B swap)...
...else return 0 (A and B stay)...
...increment counter...
*/
while (i < sortOrder.length && result === 0) {
let A = a[sortOrder[i].key],
B = b[sortOrder[i].key];
result = A < B ? -1 : A > B ? 1 : 0;
i++;
}
return result;
});
}
console.log(JSON.stringify(compare(userCards, orderKey)));
Upvotes: 0
Reputation: 833
function compare(a, b) {
if (a.unit == b.unit) {
return a.order - b.order;
}
return a.unit - b.unit;
}
Upvotes: 2