JavaScript:对字符串数字数组进行排序

11
我有一个学校分数的数组,如下所示。
(请注意,“N”表示没有分数,“K”表示幼儿园)
const toSort = ['1','3','4','5','6','7','9','10','11','12','K','2','N','8'];
我想使用JavaScript sort()方法来排列数组,以便它看起来像:
const sorted = ['K','1','2','3','4','5','6','7','8','9','10','11','12','N'];
以下是我的尝试:

const toSort = ['1', '3', '4', '5', '6', '7', '9', '10', '11', '12', 'K', '2', 'N', '8'];

toSort.sort();
// Produces: ["1", "10", "11", "12", "2", "3", "4", "5", "6", "7", "8", "9", "K", "N"]

const test = toSort.sort((a, b) => {
  if (a === 'K') {
    return -1;
  }

  return Number(a) < Number(b) ? -1 : Number(a) > Number(b) ? 1 : 0;
});

console.log(test)

https://jsbin.com/pocajayala/1/edit?html,js,console,output

我该如何解决这个问题?


10
为什么要在单词开头加K,结尾加N? - Zakaria Acharki
1
这些是学校成绩。'N'代表无成绩,'K'代表幼儿园。 - RyeGuy
2
就像 'K' 一样,为 'N' 做一个特殊情况。然后将其他所有内容转换为 Number。不需要任何三元运算符。 - Code-Apprentice
1
你的问题在于 Number("K")Number("N") 都是 NaN。你只移除了参数 a"K" 的情况,而没有考虑到 b"K" 或其中任意一个为 "N" 的情况。 - ASDFGerte
1
你代码的微小修复是添加 if (b === "K") return 1; if (a === "N") return 1; if (b === "N") return -1;。但这仍然存在一个问题,因为如果比较两个相同的 "N"(在测试用例中不会发生),理论上你的排序函数就不正确了。但在我所知道的任何实现中,这并不重要。 - ASDFGerte
显示剩余2条评论
4个回答

18
你可以像这样使用字符串的本地原型localeCompare()函数:
['1', '3', '4', '5', '6', '7', '9', '10', '11', '12', 'K', '2', 'N', '8']
    .sort((a, b) => a.localeCompare(b, undefined, { numeric: true }))

//  ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "K", "N"]

它也能很好地处理数字和其他字符。


1
学会了一个新的本地函数,谢谢!这真是一个干净的解决方案。 - Yosi Leibman
这是一个非常聪明的解决方案。我真的很喜欢它。 - DevNik

6
我会像这样做:

const toSort = ['1', '3', '4', '5', '6', '7', '9', '10', '11', '12', 'K', '2', 'N', '8'];

const transform = k => {
    if (k === 'K') return 0;
    else if (k === 'N') return 13;
    else return +k;
}

const test = toSort.sort((a, b) => transform(a) - transform(b));

console.log(test);

如果您的字母与特定数字没有关联,而始终是最大和最小的,则可以在transform函数中使用Infinity-Infinity

const transform = k => {
    if (k === 'K') return -Infinity;
    else if (k === 'N') return Infinity;
    else return +k;
}

如果你想要进行代码压缩,可以将以下代码转换为:return k == 'K' ? 0 : k == 'N' ? 13 : +k - Andrew Bone

5

const toSort = ['1', '3', '4', '5', '6', '7', '9', '10', '11', '12', 'K', '2', 'N', '8'];

const test = toSort.sort((a, b) => {
 // console.log('a ' + a + ' b ' + b);
 if (a === "K" || b === "N") {
  return -1;
 }
 if (a === "N" || b === "K") {
  return 1;
 }
 return +a - +b;
});

console.log(test)


0

我认为这会对你有所帮助

const toSort = ['1','3','4','5','6','7','9','10','11','12','K','2','N','8'];

toSort.sort(function(a, b) {
  if(a == 'K') {
    return -1; // always K is smaller
  }
  if(a == 'N')  {
    return 1 // always N is bigger
  }
  if(b == 'K') {
    return 1;
  }
  if(b == 'N')  {
    return -1
  }
  return Number(a) - Number(b);
});

console.log(toSort);


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接