【问题标题】:JavaScript array.sort with multiple values (strings and numbers)具有多个值(字符串和数字)的 JavaScript array.sort
【发布时间】:2017-06-04 13:32:50
【问题描述】:

我想按subject (字符串,按字母顺序),然后级别 (int,升序)对数组进行排序,然后是 名称 (字符串,按字母顺序)。我在 SO 上找到了许多其他线程,但我没有找到任何按多个变量 types 排序的线程。我以为我有它,但它没有正确排序。

排序函数:

scipads.sort(function (a, b) {
    if (a.subject != b.subject)
        return a.subject < b.subject;
    if (a.level != b.level)
        return a.level - b.level;
    return a.name < b.name;
});

数组:

var scipads = [{
        "name": "L2 Physics Externals",
        "level": 2,
        "subject": "physics",
    }, {
        "name": "L2 Physics Internals",
        "level": 2,
        "subject": "physics",
    }, {
        "name": "L2 Chem Externals",
        "level": 2,
        "subject": "chemistry",
    }, {
        "name": "L2 Chem Internals",
        "level": 2,
        "subject": "chemistry",
    }, {
        "name": "L2 Bio Internals",
        "level": 2,
        "subject": "biology",
    }, {
        "name": "L2 Bio Externals",
        "level": 2,
        "subject": "biology",
    }, {
        "name": "L1 Electricity & Magnetism",
        "level": 1,
        "subject": "physics",
    }, {
        "name": "L1 Wave Behaviour",
        "level": 1,
        "subject": "physics",
    }, {
        "name": "L1 Heat",
        "level": 1,
        "subject": "physics",
    }, {
        "name": "L1 Carbon Chemistry",
        "level": 1,
        "subject": "chemistry",
    }, {
        "name": "L1 Selected Elements",
        "level": 1,
        "subject": "chemistry",
    }, {
        "name": "L1 Chemical Reactions",
        "level": 1,
        "subject": "chemistry",
    },
];

如何按主题、级别、名称排序?

【问题讨论】:

  • 也许先按主题排序,然后将具有相同主题的所有项目放入一个新列表并按级别排序,然后对名称进行相同操作,最后将其拼凑在一起?
  • 字符串需要与a.subject.localeCompare(b.subject)进行比较。排序函数需要返回一个正值或负值或零。目前对于字符串,它只返回 truefalse 反映正数和零。缺少负片。
  • 所以如果它是假的,它应该返回-1?
  • @DarkMatterMatt 每当第一个值需要第二个值出现时,它都需要返回-1
  • 您可以将所有内容简化为scipads.sort((a, b) =&gt; a.subject.localeCompare(b.subject) || a.level - b.level || a.name.localeCompare(b.name));

标签: javascript arrays sorting


【解决方案1】:

比较应该return an integer。这是一个例子:

scipads.sort((a, b) => {
    if (a.subject != b.subject) { 
        return a.subject < b.subject ? -1 : 1; 
    }
    if (a.level != b.level) { 
        return a.level - b.level; 
    }
    return a.name < b.name ? -1 : 1;
})

【讨论】:

  • 嘿,不错的箭头运算符。每天学习新东西。
  • @DarkMatterMatt 箭头操作符是 ES6 中引入的一个叫做“箭头函数”的特性。
  • 为了正确起见,您能否将&lt;s 编辑为&gt;s。它正在对 Z-A 进行排序。
  • @DarkMatterMatt 你能仔细检查一下吗?它在我这边排序正确:)
  • 哈哈是的,我的错,我以为是? 1 : -1; 而不是相反。对不起:P
【解决方案2】:

使用localeCompare 比较字符串

var scipads=[{name:"L2 Physics Externals",level:2,subject:"physics"},{name:"L2 Physics Internals",level:2,subject:"physics"},{name:"L2 Chem Externals",level:2,subject:"chemistry"},{name:"L2 Chem Internals",level:2,subject:"chemistry"},{name:"L2 Bio Internals",level:2,subject:"biology"},{name:"L2 Bio Externals",level:2,subject:"biology"},{name:"L1 Electricity & Magnetism",level:1,subject:"physics"},{name:"L1 Wave Behaviour",level:1,subject:"physics"},{name:"L1 Heat",level:1,subject:"physics"},{name:"L1 Carbon Chemistry",level:1,subject:"chemistry"},{name:"L1 Selected Elements",level:1,subject:"chemistry"},{name:"L1 Chemical Reactions",level:1,subject:"chemistry"}];

scipads.sort(function(a, b) {
  if (a.subject != b.subject)
    return a.subject.localeCompare(b.subject);
  else if (a.level != b.level)
    return a.level - b.level;
  return a.name.localeCompare(b.name);
});

console.log(scipads);

【讨论】:

  • 接受了您的答案,因为正确的大小写处理(和正确的排序方式)
  • 谢谢,localeCompare 对非英文字符也很有用。
【解决方案3】:

您的排序比较功能很接近,但还没有完全开启。您应该返回 -1 表示小于,0 表示等于,1 表示大于。有关文档,请参阅 here

示例:将return a.subject &lt; b.subject 更改为return a.subject &lt; b.subject ? -1 : 1;

【讨论】:

  • 谢谢,我自己搞定了:P(感谢 Xufox)。我可以在 5 分钟内接受这个答案。
  • 很高兴它来找你!
【解决方案4】:

要比较字符串,您应该使用string.localeCompare。此外,您可以尝试创建一个具有优先级列表的数组并循环对其进行排序。

var scipads=[{name:"L2 Physics Externals",level:2,subject:"physics"},{name:"L2 Physics Internals",level:2,subject:"physics"},{name:"L2 Chem Externals",level:2,subject:"chemistry"},{name:"L2 Chem Internals",level:2,subject:"chemistry"},{name:"L2 Bio Internals",level:2,subject:"biology"},{name:"L2 Bio Externals",level:2,subject:"biology"},{name:"L1 Electricity & Magnetism",level:1,subject:"physics"},{name:"L1 Wave Behaviour",level:1,subject:"physics"},{name:"L1 Heat",level:1,subject:"physics"},{name:"L1 Carbon Chemistry",level:1,subject:"chemistry"},{name:"L1 Selected Elements",level:1,subject:"chemistry"},{name:"L1 Chemical Reactions",level:1,subject:"chemistry"}];

var priority = ["subject", "level", "name"]

scipads.sort(function(a,b){
  var val = 0;
  priority.some(function(k){
    val = compare(a,b,k);
    return val !== 0;
  });
})

function compare(a,b,k){
  switch(typeof a[k]){
    case "string": return a[k].localeCompare(b[k]);
    case "number": return a[k] - b[k]
  }
}

console.log(scipads)

【讨论】:

    【解决方案5】:

    我的解决办法,先比较科目,再比较水平

    var scipads=[{name:"L2 Physics Externals",level:2,subject:"physics"},{name:"L2 Physics Internals",level:2,subject:"physics"},{name:"L2 Chem Externals",level:2,subject:"chemistry"},{name:"L2 Chem Internals",level:2,subject:"chemistry"},{name:"L2 Bio Internals",level:2,subject:"biology"},{name:"L2 Bio Externals",level:2,subject:"biology"},{name:"L1 Electricity & Magnetism",level:1,subject:"physics"},{name:"L1 Wave Behaviour",level:1,subject:"physics"},{name:"L1 Heat",level:1,subject:"physics"},{name:"L1 Carbon Chemistry",level:1,subject:"chemistry"},{name:"L1 Selected Elements",level:1,subject:"chemistry"},{name:"L1 Chemical Reactions",level:1,subject:"chemistry"}];
    
    // sort by subject, then level, then name
    var res = scipads.sort((a, b) => {
      if (a.subject > b.subject) {
        return 1;
      } else if (a.subject < b.subject) {
        return -1;
      } else if ( a.level > b.level){
        return 1;
      } else if (a.level < b.level) {
        return -1;
      } else if (a.name > b.name) {
        return 1;
      } else if (a.name < b.name) {
        return -1;
      }
      return 0;
    });
    
    
    console.log(res)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-03-10
      • 2011-06-14
      相关资源
      最近更新 更多