【问题标题】:Inconsistent Alphanumeric Sorting with ag-grid and String Cells [duplicate]使用 ag-grid 和字符串单元格的字母数字排序不一致 [重复]
【发布时间】:2019-12-22 23:31:59
【问题描述】:

我正在使用 ag-grid-react 显示来自端点的数据表。我有一列包含字母数字值,需要使用“自然”排序算法进行排序(即数字组合在一起,字母数字字符串组合在一起......)

下面是我的列定义。网格上启用了排序,当我单击列对网格进行排序时,除了 some 字符串以中断以 C 开头的字符串序列之外,所有内容都显示为已排序。

这发生在 ag-grid 的默认排序算法中,无论 accentedSort 是真还是假,甚至使用基本的自定义排序比较器(见下文)。

列定义:


        field: 'cqttUnitPayItemDescriptionId',
        headerName: 'Description',
        type: 'dropdown',
        editable: true,
        resizable: true,
        valueGetter: (p) => {
            const value = p.data[p.colDef.field];
            const cellDescription = p.data.description;

            // returns a string value for display
            // `items` is an ImmutableJs Map of objects, grouped by index, containing a `description` string property.
            return value >= 0 ? items.getIn([value, 'description']) || cellDescription : value; 
        },
        cellEditorFramework: AgGridCellEditor({ component: AgDropdownEditor, renderProps: innerProps => ({ createable: true, labelProperty: 'description', options: itemsByUnitPayItemId.getIn([innerProps.data.unitPayItemId], Map()).toList(), ...innerProps }) }),
        sortable: true,
        width: 250,
        comparator: StringComparator
    },

自定义排序比较器:

export function StringComparator(valueA: string = '', valueB: string = '') {
    const valueALower = valueA.toLowerCase();
    const valueBLower = valueB.toLowerCase();
    return valueALower.localeCompare(valueBLower, 'en', { numeric: true });
}

排序不一致的视觉示例:

鉴于上面的屏幕截图:比较器的手动测试显示字符串“4' x 8' x 16' (Dragline Mat)”应该出现在“Construction Crew “Move Around” - Tie-Ins” 之前(即调用的返回值具有这些参数的比较器分别为-1)但显然网格不这么认为。可能是我遗漏了有关对比较器函数的调用范围的一些信息吗?

【问题讨论】:

  • 请参考以上链接!!我实际上已经回答了一个类似的问题。基本上,您可能已经意识到,您需要提供一个自定义验证器。
  • 这不是一个类似的问题。我在发布之前查看了您的问题。当我发布此问题时,尽管使用了您的答案,但排序似乎不一致。您的回答没有解决我的问题的原因已在我对自己问题的回答中说明。

标签: sorting ecmascript-6 ag-grid


【解决方案1】:

原来一些被排序的字符串在字符串的开头包含一个空格,导致它们(正确地)在数字和字母字符之前排序。我通过简单地将.trim() 附加到StringComparator 中要比较的每个值的末尾来解决了这个问题:

export function StringComparator(valueA: string = '', valueB: string = '') {
    const valueALower = valueA.toLowerCase().trim();
    const valueBLower = valueB.toLowerCase().trim();
    return valueALower.localeCompare(valueBLower, 'en', { numeric: true });
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-10-14
    • 2021-01-25
    • 1970-01-01
    • 2021-07-13
    • 1970-01-01
    • 2012-04-16
    • 2020-05-04
    相关资源
    最近更新 更多