I'm trying to sort the cars by model
and month
and it works well.
But I have an average month 00
which I want to be the last record of each model instead of the first.
I have no idea how to achieve this. I have created a snippet. Any help please?
let cars = [{
model: 'Ford',
month: '12'
}, {
model: 'Ford',
month: '03'
}, {
model: 'Ford',
month: '01'
}, {
model: 'Ford',
month: '00'
},
{
model: 'Ford',
month: '05'
},
{
model: 'Fiat',
month: '05'
},
{
model: 'Fiat',
month: '01'
},
{
model: 'Fiat',
month: '00'
}
];
console.log(`Unsorted cars: ${JSON.stringify(cars)}`);
const sorted = cars.sort((a, b) => a.model.localeCompare(b.model) || a.month.localeCompare(b.month));
console.log(`Sorted cars: ${JSON.stringify(sorted)}`);
Got:
[{"model":"Fiat","month":"00"},{"model":"Fiat","month":"01"},{"model":"Fiat","month":"05"},{"model":"Ford","month":"00"},{"model":"Ford","month":"01"},{"model":"Ford","month":"03"},{"model":"Ford","month":"05"},{"model":"Ford","month":"12"}]
Expected:
[{"model":"Fiat","month":"01"},{"model":"Fiat","month":"05"}, {"model":"Fiat","month":"00"},{"model":"Ford","month":"01"},{"model":"Ford","month":"03"},{"model":"Ford","month":"05"},{"model":"Ford","month":"12"}, {"model":"Ford","month":"00"}]
CodePudding user response:
You could special-case the 00
month in your sort comparator function:
let cars = [
{ model: 'Ford', month: '12' },
{ model: 'Ford', month: '03' },
{ model: 'Ford', month: '01' },
{ model: 'Ford', month: '00' },
{ model: 'Ford', month: '05' },
{ model: 'Fiat', month: '05' },
{ model: 'Fiat', month: '01' },
{ model: 'Fiat', month: '00' }
];
console.log(`Unsorted cars: ${JSON.stringify(cars)}`);
const sorted = cars.sort((a, b) =>
a.model.localeCompare(b.model) ||
(a.month == '00' ? 1 : (b.month == '00' ? -1 : a.month.localeCompare(b.month)))
);
console.log(`Sorted cars: ${JSON.stringify(sorted)}`);
// alternate solution without nested ternary operator
const sorted2 = cars.sort((a, b) =>
a.model.localeCompare(b.model) ||
a.month == '00' ||
(b.month == '00' ? -1 : a.month.localeCompare(b.month))
);
console.log(`Sorted cars: ${JSON.stringify(sorted2)}`);
CodePudding user response:
There are actually 12 months in a year. (I know right)
You can safely convert the month '00'
to '13'
and keep your sorting as-is
Eventually convert back '13'
to '00'
This is not the best solution concerning the performance, but it's easy to set up and maintain :
let cars = [{
model: 'Ford',
month: '12'
}, {
model: 'Ford',
month: '03'
}, {
model: 'Ford',
month: '01'
}, {
model: 'Ford',
month: '00'
},
{
model: 'Ford',
month: '05'
},
{
model: 'Fiat',
month: '05'
},
{
model: 'Fiat',
month: '01'
},
{
model: 'Fiat',
month: '00'
}
];
console.log(`Unsorted cars: ${JSON.stringify(cars)}`);
// replace the '00'
const ZeroFixed = cars.map(elem => { if (elem.month === '00') elem.month = '13'; return elem });
const sorted = ZeroFixed.sort((a, b) => a.model.localeCompare(b.model) || a.month.localeCompare(b.month));
// replace back the '13'
const SortedZeroFixed = cars.map(elem => { if (elem.month === '13') elem.month = '00'; return elem });
console.log(`Sorted cars: ${JSON.stringify(SortedZeroFixed)}`);