JavaScript数组自定义sort结合localeCompare排序异常排查
排序函数逻辑疑问:LeetCode场景下的字符串排序异常
我在解决LeetCode问题《Sender With Largest Word Count》时,碰到了一个调试许久都没搞懂的排序问题。
给定如下二维数组:
let items = [ [ 'K', 4 ], [ 'kFIbpoFxn', 10 ], [ 'yErgn', 6 ], [ 'N', 8 ], [ 'wtJesr', 9 ], [ 'rusffeL', 14 ], [ 'KlpoodEd', 5 ], [ 'qGcQqIVdFr', 1 ], [ 'ztmCdK', 10 ], [ 'HFILjKln', 12 ], [ 'TmmQZ', 18 ], [ 'R', 7 ], [ 'CNh', 7 ], [ 'YMQDBkOWy', 22 ], [ 'kjiSc', 4 ], [ 'cGMsZxxx', 6 ], [ 'PPqsmNBewN', 21 ], [ 'gbtn', 10 ], [ 'nQNcL', 8 ], [ 'rK', 10 ], [ 'ppr', 16 ], [ 'LhSVp', 11 ], [ 'Ub', 7 ], [ 'QGRFMLY', 11 ], [ 'SdDObYkD', 9 ], [ 'q', 3 ], [ 'suAakSCuHz', 6 ], [ 'dnzhjdwrEt', 8 ], [ 'ubIEXAO', 22 ], [ 'EsBuLal', 11 ], [ 'xlQqQRrdTv', 12 ], [ 'mWxCG', 8 ], [ 'DmwIEmS', 5 ], [ 'nBQLLS', 6 ], [ 'QhF', 4 ], [ 'bmtYQKYv', 5 ], [ 'PRiNk', 7 ], [ 'QyYJw', 7 ], [ 'QIFauTN', 3 ], [ 'zJLcUq', 13 ], [ 'TU', 1 ], [ 'lCkGjDY', 7 ], [ 'A', 6 ] ]
我的排序需求是:
- 优先按数组第二个元素(整数)降序排列
- 若整数相等,则按第一个元素(字符串)的字典序降序排列(和JavaScript默认字符串排序方向相反)
使用的排序代码如下:
items.sort(function(a, b) { return b[1] !== a[1] ? b[1] - a[1] : -a[0].localeCompare(b[0]); });
排序后的结果如下:
[ [ 'YMQDBkOWy', 22 ], [ 'ubIEXAO', 22 ], [ 'PPqsmNBewN', 21 ], [ 'TmmQZ', 18 ], [ 'ppr', 16 ], [ 'rusffeL', 14 ], [ 'zJLcUq', 13 ], [ 'xlQqQRrdTv', 12 ], [ 'HFILjKln', 12 ], [ 'QGRFMLY', 11 ], [ 'LhSVp', 11 ], [ 'EsBuLal', 11 ], [ 'ztmCdK', 10 ], [ 'rK', 10 ], [ 'kFIbpoFxn', 10 ], [ 'gbtn', 10 ], [ 'wtJesr', 9 ], [ 'SdDObYkD', 9 ], [ 'nQNcL', 8 ], [ 'N', 8 ], [ 'mWxCG', 8 ], [ 'dnzhjdwrEt', 8 ], [ 'Ub', 7 ], [ 'R', 7 ], [ 'QyYJw', 7 ], [ 'PRiNk', 7 ], [ 'lCkGjDY', 7 ], [ 'CNh', 7 ], [ 'yErgn', 6 ], [ 'suAakSCuHz', 6 ], [ 'nBQLLS', 6 ], [ 'cGMsZxxx', 6 ], [ 'A', 6 ], [ 'KlpoodEd', 5 ], [ 'DmwIEmS', 5 ], [ 'bmtYQKYv', 5 ], [ 'QhF', 4 ], [ 'kjiSc', 4 ], [ 'K', 4 ], [ 'QIFauTN', 3 ], [ 'q', 3 ], [ 'TU', 1 ], [ 'qGcQqIVdFr', 1 ] ]
问题点
按照需求,'ubIEXAO'应该排在'YMQDBkOWy'前面,但实际排序结果正好相反。
单独测试-a.localeCompare(b)时结果是正确的,但放到数组排序函数里就没生效。更奇怪的是:我发现硬编码返回-1,和返回-a.localeCompare(b)(控制台输出值也是-1)的排序结果不一样,完全搞不懂这个交互逻辑。
(注:我知道有其他解法,现在只想弄明白当前这个排序函数失效的原因)
测试验证代码
let a = 'YMQDBkOWy'; let b = 'ubIEXAO'; console.log('localeCompare test: ' + -a.localeCompare(b)) let c = [a,b] console.log(c.sort( (a,b) => {console.log('1'); return -a.localeCompare(b)})) c = [a,b] console.log(c.sort( (a,b) => {return -1}))
内容的提问来源于stack exchange,提问作者BinarySolo
相关产品推荐
相关产品推荐

