Tooltip: Sort decimals using standard numeric compare (#49084)

* Failing test case

* Compare numeric values not using collator
This commit is contained in:
Dominik Prokop
2022-05-17 16:30:44 +02:00
committed by GitHub
parent 457ee6d2fb
commit 6a5a0e5770
2 changed files with 26 additions and 14 deletions

View File

@@ -7,21 +7,24 @@ describe('arrayUtils', () => {
const testArrayNumeric = [1, 10, null, 2, undefined, 5, 6, ' ', 7, 9, 8, 3, 4];
const testArrayString = ['1', '10', null, '2', undefined, '5', '6', ' ', '7', '9', '8', '3', '4'];
const testArrayFloatingPoint = ['1.0', '2.7', '0.5', ' ', null, '2', undefined];
const testArrayVariableFloatingPoint = [1.1234567, 2.7, 1.23456, ' ', null, 2, undefined];
const testArrayText = ['baz', ' ', 'foo', null, 'bar', undefined];
const testArrayMixed = ['baz', ' ', 1, 'foo', '1.5', '0.5', null, 'bar', undefined];
it.each`
order | testArray | expected
${SortOrder.Ascending} | ${testArrayNumeric} | ${[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, ' ', null, undefined]}
${SortOrder.Descending} | ${testArrayNumeric} | ${[10, 9, 8, 7, 6, 5, 4, 3, 2, 1, ' ', null, undefined]}
${SortOrder.Ascending} | ${testArrayString} | ${['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', ' ', null, undefined]}
${SortOrder.Descending} | ${testArrayString} | ${['10', '9', '8', '7', '6', '5', '4', '3', '2', '1', ' ', null, undefined]}
${SortOrder.Ascending} | ${testArrayFloatingPoint} | ${['0.5', '1.0', '2', '2.7', null, ' ', undefined]}
${SortOrder.Descending} | ${testArrayFloatingPoint} | ${['2.7', '2', '1.0', '0.5', null, ' ', undefined]}
${SortOrder.Ascending} | ${testArrayText} | ${['bar', 'baz', 'foo', null, ' ', undefined]}
${SortOrder.Descending} | ${testArrayText} | ${['foo', 'baz', 'bar', null, ' ', undefined]}
${SortOrder.Ascending} | ${testArrayMixed} | ${['0.5', 1, '1.5', 'bar', 'baz', 'foo', null, ' ', undefined]}
${SortOrder.Descending} | ${testArrayMixed} | ${['foo', 'baz', 'bar', '1.5', 1, '0.5', null, ' ', undefined]}
order | testArray | expected
${SortOrder.Ascending} | ${testArrayNumeric} | ${[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, ' ', null, undefined]}
${SortOrder.Descending} | ${testArrayNumeric} | ${[10, 9, 8, 7, 6, 5, 4, 3, 2, 1, ' ', null, undefined]}
${SortOrder.Ascending} | ${testArrayString} | ${['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', ' ', null, undefined]}
${SortOrder.Descending} | ${testArrayString} | ${['10', '9', '8', '7', '6', '5', '4', '3', '2', '1', ' ', null, undefined]}
${SortOrder.Ascending} | ${testArrayFloatingPoint} | ${['0.5', '1.0', '2', '2.7', null, ' ', undefined]}
${SortOrder.Descending} | ${testArrayFloatingPoint} | ${['2.7', '2', '1.0', '0.5', null, ' ', undefined]}
${SortOrder.Ascending} | ${testArrayText} | ${['bar', 'baz', 'foo', null, ' ', undefined]}
${SortOrder.Descending} | ${testArrayText} | ${['foo', 'baz', 'bar', null, ' ', undefined]}
${SortOrder.Ascending} | ${testArrayMixed} | ${['0.5', 1, '1.5', 'bar', 'baz', 'foo', null, ' ', undefined]}
${SortOrder.Descending} | ${testArrayMixed} | ${['foo', 'baz', 'bar', '1.5', 1, '0.5', null, ' ', undefined]}
${SortOrder.Ascending} | ${testArrayVariableFloatingPoint} | ${[1.1234567, 1.23456, 2, 2.7, null, ' ', undefined]}
${SortOrder.Descending} | ${testArrayVariableFloatingPoint} | ${[2.7, 2, 1.23456, 1.1234567, null, ' ', undefined]}
`('$order', ({ order, testArray, expected }) => {
const sorted = [...testArray].sort(sortValues(order));
expect(sorted).toEqual(expected);

View File

@@ -12,6 +12,8 @@ export function moveItemImmutably<T>(arr: T[], from: number, to: number) {
* Null/undefined/empty string values are always sorted to the end regardless of the sort order provided
*/
const collator = new Intl.Collator(undefined, { numeric: true, sensitivity: 'base' });
const numericCompare = (a: number, b: number) => a - b;
export function sortValues(sort: SortOrder.Ascending | SortOrder.Descending) {
return (a: any, b: any) => {
if (a === b) {
@@ -25,9 +27,16 @@ export function sortValues(sort: SortOrder.Ascending | SortOrder.Descending) {
return 1;
}
if (sort === SortOrder.Descending) {
return collator.compare(b, a);
let compareFn: (a: any, b: any) => number = collator.compare;
if (typeof a === 'number' && typeof b === 'number') {
compareFn = numericCompare;
}
return collator.compare(a, b);
if (sort === SortOrder.Descending) {
return compareFn(b, a);
}
return compareFn(a, b);
};
}