首页 > 解决方案 > Javascript 对 HTML 表中的空值排序错误

问题描述

我正在使用下面的 JavaScript 代码按字母和数字对表格进行排序。但是,它将具有null值的行放在顶部而不是底部。

在下图中,取自我正在处理的这个URL,当在 Rank Change 列中从大到小对表格进行排序时,空值位于顶部而不是底部。

*在此表中,Null值是带有 NEW 标记或破折号的单元格。*该问题适用于所有列/行

不应该将 Null 归类为小于 1 并按此类排序吗?我究竟做错了什么?

非常感谢任何帮助。

在此处输入图像描述

const getCellValue = (tr, idx) => tr.children[idx].innerText || tr.children[idx].textContent;

const comparer = (idx, asc) => (a, b) => ((v1, v2) => 
    v1 !=='' && v2 !=='' && !isNaN(v1) && !isNaN(v2) ? v1 - v2 : v1.toString().localeCompare(v2)
    )(getCellValue(asc ? a : b, idx), getCellValue(asc ? b : a, idx));

document.querySelectorAll('th').forEach(th => th.addEventListener('click', (() => {
    const table = th.closest('table');
    Array.from(table.querySelectorAll('tr:nth-child(n+2)'))
        .sort(comparer(Array.from(th.parentNode.children).indexOf(th), this.asc = !this.asc))
        .forEach(tr => table.appendChild(tr) );
})));

标签: javascripthtmlsortingnull

解决方案


您可以null先检查值,然后检查两个值的有限性,例如可强制为数字的数字或字符串,然后获取数字的增量或按字符串排序。

例子:

 v1   v2  (v1 === null) - (v2 === null) isFinite(v1) && isFinite(v2)             result
---- ---- ----------------------------- ---------------------------------------- ------
null null       true -  true ->  0       true -> v1 - v2                             0
null abc        true - false ->  1                                                   1
null  2         true - false ->  1                                                   1
abc  null      false -  true -> -1                                                  -1
 2   null      false -  true -> -1                                                  -1
abc  abc       false - false ->  0      false -> v1.toString().localeCompare(v2)     0
abc   2        false - false ->  0      false -> v1.toString().localeCompare(v2)     1
 2   abc       false - false ->  0      false -> v1.toString().localeCompare(v2)    -1
 2    2        false - false ->  0       true -> v1 - v2                             0

代码:

const comparer = (idx, asc) => (a, b) => ((v1, v2) =>
    (v1 === null) - (v2 === null) ||
    (isFinite(v1) && isFinite(v2)
        ? v1 - v2
        : v1.toString().localeCompare(v2)
    )
)(getCellValue(asc ? a : b, idx), getCellValue(asc ? b : a, idx));

工作示例:

var array = [null, 2, 1, 20, 11, 'b', 'aaa', 'a', null];

array.sort((v1, v2) => 
    (v1 === null) - (v2 === null) ||
    (isFinite(v1) && isFinite(v2)
        ? v1 - v2
        : v1.toString().localeCompare(v2)
    )
);

console.log(...array);


推荐阅读