I have an array that stores a prefered order, and a larger array that I need to sort:
const months = ['March', 'Jan', 'Feb', 'Dec'];
const prefOrder = ['Feb', 'March']
months.sort((a, b) => (prefOrder.indexOf(a) - prefOrder.indexOf(b)));
// desired output: ['Feb', 'March', 'Dec', 'Jan']
// or: ['Feb', 'March', 'Jan', 'Dec' ]
console.log(months);
However, when two items being compared are not in the list (i.e. (prefOrder.indexOf(a) - prefOrder.indexOf(b))
gives (-1) - (-1) = 0)
) rather than them being at the end, they end up at the start... even though if you a
not in the prefered order list, and b
in the list, you'd get (-1) - positive = negative
so a
should be sorted after b
.
How can I get use the preferred order list to put unlisted item at the end?
CodePudding user response:
You could add one for getting a falsy value for unknown values and take a large value instead to move this items to the end of the known items.
const
months = ['March', 'Jan', 'Feb', 'Dec'],
prefOrder = ['Feb', 'March'];
months.sort((a, b) =>
(prefOrder.indexOf(a) 1 || Number.MAX_VALUE) -
(prefOrder.indexOf(b) 1 || Number.MAX_VALUE)
);
console.log(months);
Instead of using an array, take an object with wanted order and move unknown items to the end with a large default value.
const
months = ['March', 'Jan', 'Feb', 'Dec'],
order = { Feb: 1, March: 2 };
months.sort((a, b) =>
(order[a] || Number.MAX_VALUE) -
(order[b] || Number.MAX_VALUE)
);
console.log(months);
CodePudding user response:
I will do that this way...
const
months = ['March', 'Jan', 'Feb', 'Dec']
, prefOrder = ['Feb', 'March']
;
months.sort((a, b) =>
{
if (!prefOrder.includes(a)) return 1
if (!prefOrder.includes(b)) return -1
return (prefOrder.indexOf(a) - prefOrder.indexOf(b))
})
console.log( JSON.stringify( months ))