Skip to content

Commit

Permalink
fix: better alphanumeric sort of bools and floats (fix #5108) (#5109)
Browse files Browse the repository at this point in the history
* Fix alphanumeric sort bool support (fix #5108)

* Fix alphanumeric sort float support (fix #5108)
  • Loading branch information
itsmejoeeey authored Oct 7, 2023
1 parent 171648e commit 3f9d382
Show file tree
Hide file tree
Showing 2 changed files with 90 additions and 0 deletions.
80 changes: 80 additions & 0 deletions packages/table-core/__tests__/Sorting.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
import {
ColumnDef,
createTable,
getCoreRowModel,
getSortedRowModel,
} from '../src'

describe('Sorting', () => {
describe('alphanumeric sort booleans ascending', () => {
it('should return rows in correct ascending order', () => {
const data = [
{ value: false },
{ value: true },
{ value: false },
{ value: true },
]
const columns: ColumnDef<{value: boolean}>[] = [{
accessorKey: "value",
header: "Value",
sortingFn: "alphanumeric"
}]

const table = createTable({
onStateChange() {},
renderFallbackValue: '',
data,
state: { sorting: [{
id: "value",
desc: false,
}]},
columns,
getCoreRowModel: getCoreRowModel(),
getSortedRowModel: getSortedRowModel(),
})

const rowModel = table.getSortedRowModel()

expect(rowModel.rows[0].getValue("value")).toBe(false)
expect(rowModel.rows[1].getValue("value")).toBe(false)
expect(rowModel.rows[2].getValue("value")).toBe(true)
expect(rowModel.rows[3].getValue("value")).toBe(true)
})
})

describe('alphanumeric sort floats ascending', () => {
it('should return rows in correct ascending order', () => {
const data = [
{ value: 0.85 },
{ value: 0.001000000047 },
{ value: 0.2000016 },
{ value: 0.002002 },
]
const columns: ColumnDef<{value: number}>[] = [{
accessorKey: "value",
header: "Value",
sortingFn: "alphanumeric"
}]

const table = createTable({
onStateChange() {},
renderFallbackValue: '',
data,
state: { sorting: [{
id: "value",
desc: false,
}]},
columns,
getCoreRowModel: getCoreRowModel(),
getSortedRowModel: getSortedRowModel(),
})

const rowModel = table.getSortedRowModel()

expect(rowModel.rows[0].getValue("value")).toBe(0.001000000047)
expect(rowModel.rows[1].getValue("value")).toBe(0.002002)
expect(rowModel.rows[2].getValue("value")).toBe(0.2000016)
expect(rowModel.rows[3].getValue("value")).toBe(0.85)
})
})
})
10 changes: 10 additions & 0 deletions packages/table-core/src/sortingFns.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,9 @@ function compareBasic(a: any, b: any) {
}

function toString(a: any) {
if (typeof a === 'boolean') {
return String(a)
}
if (typeof a === 'number') {
if (isNaN(a) || a === Infinity || a === -Infinity) {
return ''
Expand All @@ -71,6 +74,13 @@ function toString(a: any) {
// It handles numbers, mixed alphanumeric combinations, and even
// null, undefined, and Infinity
function compareAlphanumeric(aStr: string, bStr: string) {
// Check if the string contains only a number
const aFloat = parseFloat(aStr);
const bFloat = parseFloat(bStr);
if(!isNaN(aFloat) && !isNaN(bFloat)) {
return compareBasic(aFloat, bFloat)
}

// Split on number groups, but keep the delimiter
// Then remove falsey split values
const a = aStr.split(reSplitAlphaNumeric).filter(Boolean)
Expand Down

0 comments on commit 3f9d382

Please sign in to comment.