How To Sort An Array Of Objects With Labels According To Other Array Of Labels?
Solution 1:
There are a couple of approaches:
Using
indexOf
to repeatedly search thelabels
arrayUsing a map so looking up the index of a label is quicker
Here's an example using indexOf
(in ES2015+):
arrayToBeSorted.sort((a, b) => labels.indexOf(a.label) - labels.indexOf(b.label));
Live Copy:
var arrayToBeSorted = [{label: 'firstLabel', value: 123}, {label: 'secondLabel', value: 456}, {label: 'thirdLabel', value: 789}];
var labels = ['secondLabel', 'thirdLabel', 'fourthLabel', 'firstLabel'];
arrayToBeSorted.sort((a, b) => labels.indexOf(a.label) - labels.indexOf(b.label));
console.log(arrayToBeSorted);
Note that indexOf
will return -1
if the label doesn't exist in labels
, which will make unknown labels appear at the beginning of the result. If you want them at the end instead, check for -1
and replace it with Infinity
.
Here's an example using a map to speed up finding those indexes (in ES2015+):
const map = newMap(labels.map((label, index) => [label, index]));
arrayToBeSorted.sort((a, b) => {
let aindex = map.get(a.label);
if (aindex === null) {
aindex = -1; // Or Infinity if you want them at the end
}
let bindex = map.get(b.label);
if (bindex === null) {
bindex = -1; // ""
}
return aindex - bindex;
});
Live Copy:
var arrayToBeSorted = [{label: 'firstLabel', value: 123}, {label: 'secondLabel', value: 456}, {label: 'thirdLabel', value: 789}];
var labels = ['secondLabel', 'thirdLabel', 'fourthLabel', 'firstLabel'];
const map = newMap(labels.map((label, index) => [label, index]));
arrayToBeSorted.sort((a, b) => {
let aindex = map.get(a.label);
if (aindex === null) {
aindex = -1; // Or Infinity if you want them at the end
}
let bindex = map.get(b.label);
if (bindex === null) {
bindex = -1; // ""
}
return aindex - bindex;
});
console.log(arrayToBeSorted);
That's written for clarity and to avoid looking up the labels more than once in the callback. It can be more concise at the cost of a second label lookup in the map:
constmap = new Map(labels.map((label, index) => [label, index]));
arrayToBeSorted.sort((a, b) => {
const aindex = map.has(a.label) ? map.get(a.label) : -1; // Or Infinity if you want them at the endconst bindex = map.has(b.label) ? map.get(b.label) : -1; // "return aindex - bindex;
});
Live Copy:
var arrayToBeSorted = [{label: 'firstLabel', value: 123}, {label: 'secondLabel', value: 456}, {label: 'thirdLabel', value: 789}];
var labels = ['secondLabel', 'thirdLabel', 'fourthLabel', 'firstLabel'];
const map = newMap(labels.map((label, index) => [label, index]));
arrayToBeSorted.sort((a, b) => {
const aindex = map.has(a.label) ? map.get(a.label) : -1; // Or Infinity if you want them at the endconst bindex = map.has(b.label) ? map.get(b.label) : -1; // "return aindex - bindex;
});
console.log(arrayToBeSorted);
It can even be:
constmap = new Map(labels.map((label, index) => [label, index]));
arrayToBeSorted.sort((a, b) =>
(map.has(a.label) ? map.get(a.label) : -1) - (map.has(b.label) ? map.get(b.label) : -1)
);
...but for me that's making life too difficult when debugging, etc.
Solution 2:
You need to provide priority to values as per second array. here we are building a Map from second array name as key and index as priority. so you can use Map
and default value
and sort
var arrayToBeSorted = [{label: 'firstLabel', value: 123}, {label: 'secondLabel', value: 456}, {label: 'thirdLabel', value: 789}]
var labels = ['secondLabel', 'thirdLabel', 'fourthLabel', 'firstLabel']
let mapper = newMap(labels.map((v, i) => [v, i + 1]))
let final = arrayToBeSorted.sort((a, b) => {
return (mapper.get(a.label) || Infinity) - (mapper.get(b.label) || Infinity)
})
console.log(final)
Solution 3:
You can create a custom order and order by it:
var arrayToBeSorted = [
{label: 'firstLabel', value: 123},
{label: 'secondLabel', value: 456},
{label: 'thirdLabel', value: 789}
];
let order = { secondLabel: 1, thirdLabel: 2, fourthLabel: 3, firstLabel: 4 };
arrayToBeSorted.sort((a, b) => {
return order[a.label] - order[b.label];
});
console.log(arrayToBeSorted);
Solution 4:
Straight-forward using sort-array.
const sortArray = require('sort-array')
const arrayToBeSorted = [
{label: 'firstLabel', value: 123},
{label: 'secondLabel', value: 456},
{label: 'thirdLabel', value: 789}
]
sortArray(arrayToBeSorted, {
by: 'label',
order: 'labelOrder',
customOrders: {
labelOrder: ['secondLabel', 'thirdLabel', 'fourthLabel', 'firstLabel']
}
})
console.log(arrayToBeSorted)
Prints this output:
[
{ label:'secondLabel', value:456 },
{ label:'thirdLabel', value:789 },
{ label:'firstLabel', value:123 }
]
Post a Comment for "How To Sort An Array Of Objects With Labels According To Other Array Of Labels?"