Javascript 在 HTML 表中对空值进行排序是错误的

Inv*_*nge 7 html javascript sorting null

我正在使用下面的 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) );
})));
Run Code Online (Sandbox Code Playgroud)

Nin*_*olz 8

您可以先检查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
Run Code Online (Sandbox Code Playgroud)

代码:

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));
Run Code Online (Sandbox Code Playgroud)

工作示例:

 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
Run Code Online (Sandbox Code Playgroud)


Van*_*jx1 6

将 null 视为 -Infinity 应该修复排序。我可以建议在 th 元素上使用 asc 属性,这样您就可以避免使用“this”。

// don't know if theres any other listeners on the th element so i clear them before use my code ( just for testing )
document.querySelectorAll('th').forEach((th, idx) => th.removeEventListener('click', () => {}, true));
document.querySelectorAll('th').forEach((th, idx) => th.addEventListener('click', (() => {
    const table = th.closest('table');
    th.asc = !th.asc;
    [...table.querySelectorAll('tr:nth-child(n+2)')]
        .sort((a, b) => +((th.asc ? a : b).children[idx].innerText || -Infinity) - +((th.asc ? b : a).children[idx].innerText || -Infinity))
        .forEach(tr => table.appendChild(tr));
})));
Run Code Online (Sandbox Code Playgroud)


Jin*_*mcg 1

如果它是 NaN,您应该将更改设置为 0 或 +-Infinity,具体取决于您希望其顶部底部或 0 更改。(仅在比较时应用值变化)

为了便于理解,我对代码进行了扩展。

检查此 ComparerNew 并根据您的需要进行修改。


const comparerNew = (idx, asc) => (a, b) => ((v1, v2) => {      
    if (isNaN(v1)) {
      v1=0; // or Infinity 
    }
    if (isNaN(v2)) {
      v2=0; // or Infinity 
    }
    return v1 !=='' && 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(comparerNew(Array.from(th.parentNode.children).indexOf(th), this.asc = !this.asc))
        .forEach(tr => table.appendChild(tr) );
  console.log("sorded");
})));

Run Code Online (Sandbox Code Playgroud)