Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(sqllab): Floating numbers not sorting correctly in result column #17573

Merged
merged 7 commits into from
Dec 4, 2021
Original file line number Diff line number Diff line change
Expand Up @@ -323,19 +323,19 @@ export default class FilterableTable extends PureComponent<

sortResults(sortBy: string, descending: boolean) {
return (a: Datum, b: Datum) => {
const aValue = a[sortBy];
const bValue = b[sortBy];
if (aValue === bValue) {
// equal items sort equally
return 0;
}
if (aValue === null) {
// nulls sort after anything else
return 1;
}
if (bValue === null) {
return -1;
}
betodealmeida marked this conversation as resolved.
Show resolved Hide resolved
// Parse any floating numbers so they'll sort correctly
const parseFloatingNums = (value: any) => {
const floatValue = parseFloat(value);
return Number.isNaN(floatValue) ? value : parseFloat(value);
};
betodealmeida marked this conversation as resolved.
Show resolved Hide resolved

const aValue = parseFloatingNums(a[sortBy]);
const bValue = parseFloatingNums(b[sortBy]);

String(aValue).localeCompare(String(bValue), undefined, {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if you're using localeCompare with the numeric option, then do you still need to convert to a float? It looks like you're converting to a float and then back again to a string? It seems redundant.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, nice find on localeCompare, but I don't think it's going to support multilingually unless you explicitly pass the language that you want to support as the second argument.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I need to parse the floating numbers for them to sort correctly, but localeCompare will only take strings. The numerical option allows it to check the strings for numbers.

Copy link
Member

@betodealmeida betodealmeida Nov 30, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@lyndsiWilliams but when you do String(aValue) and String(bValue) you're converting them back to strings. It should work if you just call localeCompare on the values without parseFloat, assuming you pass the numeric option:

"20.0".localeCompare("10", undefined, {numeric: true})
1
"2.0".localeCompare("10", undefined, {numeric: true})
-1

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did a lot of playing around with this and figured out that the sorting works without localeCompare so I removed it and added testing in this commit. While testing I found any floating point number that had more than 2 floating points (like 12.001 or longer) is a string, while any other number is a number. I think originally, the floating numbers weren't sorting correctly because the types were mixed. Just using the parseFloatingNums function seems to solve this so maybe we can look at using localeCompare in the future for multilingual sorting, since it just seems to be causing issues in this instance. I also didn't realize you had to explicitly pass the language you want to support as a second argument, so I don't think I'll be able to make this work with localeCompare.

numeric: true,
});

if (descending) {
return aValue < bValue ? 1 : -1;
}
Expand Down