我正在构建一个抽象表,表中的每一列都可以包含所有数字或所有字符串。单击列标题可以对每列进行排序。
目前我正在使用JS native sort并传递compareFunction:
const rows = [
{name: 'Adam', age: 27, rank: 3},
{name: 'Zeek', age: 31, rank: 1},
{name: 'Nancy', age: 45, rank: 4},
{name: 'Gramps', age: 102, rank: 2},
]
const compareFn = (x, y) => {
const sortDirValue = this.state.sortDirection === 'DESC' ? 1 : -1
if (x[this.state.sortBy] === y[this.state.sortBy]) return 0
return x[this.state.sortBy] < y[this.state.sortBy] ? sortDirValue : -sortDirValue
}
this.state = {
sortBy: 'name',
sortDirection: 'ASC'
}
rows.sort(compareFn)
console.log('---- Sorted by alphabetical name ----')
console.log(rows)
this.state = {
sortBy: 'age',
sortDirection: 'DESC'
}
rows.sort(compareFn)
console.log('---- Sorted by descending age ----')
console.log(rows)
&#13;
在我迄今为止尝试的所有测试案例中,这似乎都有效。但是,我知道JS可能会对排序很挑剔,比如开箱即用的sort()
sort arrays of numbers alphabetically。
我可以依靠上述方法对数字和字符串进行一致的正确排序吗?如果没有,那么这种方式的数据示例是什么样的。
答案 0 :(得分:7)
否,不能依赖于>
/ <
运算符的字母排序。这种方式不能正确排序数据的最突出的例子是混合使用大写和小写字符。
其他答案的有效之处在于使用localeCompare
是比较字符串的方法。但是,我发现字符串和数字的数字和混合也可以通过这种方式进行有效比较。
x.localeCompare(y, 'kn', { numeric: true })
通过利用numeric option localeCompare提供,我能够实现更多更强大的排序,同时还避免需要分支条件逻辑来处理每个string
和{{ 1}} case。
number
&#13;
答案 1 :(得分:3)
虽然您可以依赖于将字符串与>
和<
运算符进行比较,但我建议您改为使用String#localeCompare
。
如ECMAScript specification
所述,localeCompare
函数会在比较字符串之前进行一些检查。
您还可以在原始ECMAScript specification
中找到更多解释:
此功能旨在依赖于可用的任何语言敏感的比较功能 从主机环境到ECMAScript环境,并根据规则进行比较 主机环境的当前区域设置。强烈建议此函数处理字符串 根据Unicode标准,规范等效的是相同的(换句话说,比较 这些字符串好像它们都已经转换为标准化形式C或D首先。)
更新的代码应该是这样的:
const compareFn = (x, y) => {
if (this.state.sortDirection === 'DESC') {
return x[this.state.sortByKey].localeCompare(y[this.state.sortByKey])
} else {
return y[this.state.sortByKey].localeCompare(x[this.state.sortByKey])
}
}
rows.sort(compareFn)
答案 2 :(得分:1)
我想说在JS中比较字符串的最佳方法是localeCompare()
方法。
first_string.localeCompare(second_string);
/* Expected results:
0: exact match
-1: first_string< second_string
1: first_string> second_string
*/
<强>更新强>
.localeCompare()
允许你可能想要忽略字符串中的某些差异(例如puncutation或变音符号或case),并且仍然允许它们比较相同或者你想在决定哪些时忽略某些差异string在另一个之前。并且,它提供了许多选项来控制使用或未使用的比较功能。
如果您阅读string.prototype.localeCompare()
的{{3}},则可以看到一大堆可以传递的选项,以指定比较的工作原理。 在一个没有特殊字符的普通ascii字符串中,情况完全相同,你不太可能看到差异,但是开始涉及变音或案例问题而且localCompare()
还有更多功能和更多选项来控制比较。
可用于控制比较的一些选项: - 数字整理 - 变音敏感度 - 忽略标点符号的能力 - 案件优先 - 控制大写或小写首先比较
Morover,localeCompare()
返回perfectly aligned to use with a .sort()
回调值(负数,0或正数)。
答案 3 :(得分:1)
它将比较字符串,但特定的unicode值可能与预期的行为不同。例如,无论字母顺序如何,大写字母的值都低于小写字母。如果您要使用此功能,请记住订单是{/} / |大于小写,大于CAPITAL,大于数字,大于大多数符号(!“,)。
答案 4 :(得分:-1)