【问题标题】:.sort() acting weird with multiple arrays of text and numbers.sort() 对多个文本和数字数组表现得很奇怪
【发布时间】:2018-06-19 19:44:25
【问题描述】:

我一直在搞乱 .sort() 和 .concat() 函数,试图将多个数字和文本数组合并为一个并按时间顺序排列。如果只将数字输入到数组中,它似乎工作正常,但是一旦有文本,它似乎就会随机放置,在这种情况下在 6 到 7 之间。此外,如果我从数组中删除数字 3,则数字 4在文本之后出现乱序,都在 9 到 10 之间。如果有人可以提供帮助,我不知道为什么会这样做。

只有数字:

var multiArray = [[2, 8, 1, 7, 9], [6, 3, 5, 4, 10]];

// returns 1,10,2,3,4,5,6,7,8,9
document.write(multiArray[0]
           .concat(multiArray[1])
           .sort() 
           +"<br/>");

 // returns 1,2,3,4,5,6,7,8,9,10
document.write(multiArray[0]
               .concat(multiArray[1])
               .sort((a,b)=>a-b) 
               +"<br/>"); 

还有文字

var multiArray = [[2, 8, 1, 7, 9], [6, 3, 5, "text", 4, 10]];

// returns 1,2,3,4,5,6,text,7,8,9,10
document.write(multiArray[0]
               .concat(multiArray[1])
               .sort((a,b)=>a-b) 
               +"<br/>"); 

没有3

var multiArray = [[2, 8, 1, 7, 9], [6, 5, "text", 4, 10]];

// returns 1,2,5,6,7,8,9,text,4,10
document.write(multiArray[0]
               .concat(multiArray[1])
               .sort((a,b)=>a-b) 
               +"<br/>"); 

【问题讨论】:

  • 你希望a - b 对字符串做什么?
  • .sort() 不进行数字排序。您必须将自定义排序回调传递给它才能进行数字排序。这解释了你的第一个结果。
  • 您的第二个和第三个结果来自数字和文本的混合,但您使用的比较功能对数字和文本并不智能。垃圾进垃圾出。当你给它一个字符串和一个数字时,你的 a-b 最终会尝试进行类型强制,这只会给你一个无意义的结果。如果您要混合文本和数字,则需要一个比较函数来检测混合类型之间的比较,并准确实现您希望比较算法在这种情况下的工作方式。
  • 仅供参考,这个问题中的.concat() 与任何事情无关。如果你只是从一个平面数组开始并跳过.concat() 部分,问题是一样的。

标签: arrays sorting ecmascript-6 concatenation


【解决方案1】:

首先,将所有数组合并到一个数组中

var multiArray = [[2, 8, 1, 'foo', 7, '1', 9], [6, 5, 'text', 4, 'bar', 10]];
var flattenArray = [].concat(...multiArray);        // [ 2, 8, 1, 'foo', 7, '1', 9, 6, 5, 'text', 4, 'bar', 10 ]

然后分别对数字和字符串进行排序

const sortedNumbers = flattenArray
    .filter(n => typeof n === 'number')
    .sort((a, b) => a - b);

const sortedStrings = flattenArray
    .filter(n => typeof n === 'string')
    .sort();

最后,合并两者

const sorted = sortedNumbers.concat(sortedStrings);     // [ 1, 2, 4, 5, 6, 7, 8, 9, 10, '1', 'bar', 'foo', 'text' ]

我假设你想要数字后面的字符串。否则,只需反转串联:

const sorted = sortedStrings.concat(sortedNumbers);

【讨论】:

  • 谢谢,这很有意义。我对 .sort((a, b) => a - b) 的工作方式有点困惑,但现在我明白了。我一定一直在假设它将文本转换为 unicode 或二进制并以这种方式或其他方式对其进行排序。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-02-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-01-07
  • 1970-01-01
相关资源
最近更新 更多