【问题标题】:How to sort array of objects with forEach loop javascript [duplicate]如何使用forEach循环javascript对对象数组进行排序[重复]
【发布时间】:2019-08-15 00:19:35
【问题描述】:

我有一个如下所示的数组:

order = [ "foo", "bar", "baz" ];

这个数组包含我想要对我的对象数组进行排序的属性值。我想对数据进行排序,以便所有名称为“foo”的对象首先出现,然后是“bar”,然后是“baz”。我的对象数组看起来像这样:

data = [ 
    {name: "foo", score: 8},
    {name: "baz", score: 4},
    {name: "baz", score: 9}, 
    {name: "foo", score: 6}, 
    {name: "bar", score: 9} 
];

我希望数据顺序的结果看起来像这样,数组按名称排序,但名称相同时也按分数 desc 排序:

sortedData =  [ 
    {name: "foo", score: 8},
    {name: "foo", score: 6},  
    {name: "bar", score: 9},
    {name: "baz", score: 9},
    {name: "baz", score: 4} 
];

这是我目前尝试过的代码:

order.forEach(name => {
      sortedData = [...this.data].sort(function(obj1, obj2) {
            return (
              -(obj1.name)  || obj2.score < obj1.score
            );
          });
        });
console.log(sortedData);

【问题讨论】:

  • 如果您不希望原始数组发生变异,而是返回一个新的排序数组,那么请检查我的答案!

标签: javascript arrays sorting object foreach


【解决方案1】:

我们可以使用 order 数组中的数组索引进行排序。 还使用对象解构赋值来获取对象键进行比较。 如果name 键的第一次比较导致两个键相等,则使用score 键的第二个条件。

在我的回答中,我没有改变原始数组,如果需要这种行为,您可以查看此解决方案:

const order = [ "foo", "bar", "baz" ];
const data = [ 
    {name: "foo", score: 8},
    {name: "baz", score: 4},
    {name: "baz", score: 9}, 
    {name: "foo", score: 6}, 
    {name: "bar", score: 9} 
];
function sortArray(data, order){
  const sortedArr = Array.from(data).sort(({name: name1, score: score1},{name: name2, score: score2}) =>{
     return name1 === name2 ? score2 - score1 : order.indexOf(name1) - order.indexOf(name2);
  });
  return sortedArr;
}
console.log("***Sorted Array***");
console.log(sortArray(data, order));
console.log("***Original Array***");
console.log(data);

【讨论】:

    【解决方案2】:

    使用索引按顺序排序,获取索引可以使用Array#indexOf方法。要根据数字进行排序,只需返回差值即可。

    //  extract object properties for comparing
    // return difference of indexes to sort based on that
    // in case indexes are same return difference of score(to sort element with same name) 
    data.sort(({ name: a, score: as }, { name: b ,score: bs}) => order.indexOf(a) - order.indexOf(b) || bs - as)
    

    let order = ["foo", "bar", "baz"];
    let data = [{
        name: "foo",
        score: 8
      },
      {
        name: "baz",
        score: 4
      },
      {
        name: "baz",
        score: 9
      },
      {
        name: "foo",
        score: 6
      },
      {
        name: "bar",
        score: 9
      }
    ];
    
    
    data.sort(({ name: a, score : as }, { name: b ,score:bs}) => order.indexOf(a) - order.indexOf(b) || bs - as)
    
    console.log(data)

    【讨论】:

    • 谢谢你的回答,我怎么也可以按分数排序,运行代码时“baz”也不是按分数排序
    • @TeamCafe : 更新了,不管是升序还是降序?
    • 按降序,使最大分数在顶部
    • @TeamCafe : 完成 :)
    • @TeamCafe:很高兴它有帮助:)
    【解决方案3】:

    您可以简单地使用sortindexOf

    let order = [ "foo", "bar", "baz" ];
    
    let data = [ 
        {name: "foo", score: 8},
        {name: "baz", score: 4},
        {name: "baz", score: 9}, 
        {name: "foo", score: 6}, 
        {name: "bar", score: 9} 
    ];
    
    let op = data.sort((a,b)=> (order.indexOf(a.name) - order.indexOf(b.name)) || b.score - a.score )
    
    console.log(op)

    【讨论】:

    • 感谢您的回答,但是代码 sn-p 结果似乎没有按分数降序排序的名称“baz”的对象
    • @TeamCafe 在 sn-p 中仅按降序排列。再次交叉检查 mtae :)
    • 非常感谢,对不起:D
    猜你喜欢
    • 1970-01-01
    • 2011-07-27
    • 2023-03-26
    • 2018-06-05
    • 2015-03-26
    • 1970-01-01
    • 2021-10-14
    • 2014-01-25
    • 1970-01-01
    相关资源
    最近更新 更多