Example input:
[ '50-59', '60-69', '40-49', '>=70', '<40' ]
Expected output
[ '<40', '40-49', '50-59', '60-69', '>=70' ]
Attempt; expanded from my previous one-liner (for debugging):
export function sort_ranges(ranges: string[]): string[] {
const collator = new Intl.Collator(undefined, {
numeric: true,
sensitivity: 'base',
ignorePunctuation: true
});
return ranges.sort((a: string, b: string): number => {
const bNaN: boolean = !isNaN(parseInt(b[0]));
const col = () =>
console.info(`collator(${a}, ${b}) = ${collator.compare(a, b)}`
) || collator.compare(a, b);
if (a[0] === '<' && bNaN) {
console.info('< =', a);
return -1;
}
else if (a[0] === '>' || b[0] === '>') {
console.info('> =', a);
return 1;
}
else return col();
}
);
}
Runnable (mocha+chai in a plnkr)
Note: ranges are guaranteed to be non-overlapping, and there may be other things in the array like 'foo' which should be put in whatever order at the end of the array.
Ideas: I could build a new array like [[50,59], ['<', '40']]
then try overriding the .sort
method again, but that seems crazy. Is there a better solution?
var a = [ '50-59', '60-69', '40-49', '>=70', '<40' ];
a.sort(function(a,b) {
if (a[0] === '<') return -1;
if (a[0] === '>') return 1;
if (b[0] === '<') return 1;
if (b[0] === '>') return -1;
return a.match(/\d+/)[0] - b.match(/\d+/)[0];
});
console.dir( a );
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With