【问题标题】:Sorting an object of nested objects in javascript (maybe using lodash?)在javascript中对嵌套对象的对象进行排序(也许使用lodash?)
【发布时间】:2015-07-22 05:50:15
【问题描述】:

我有一个嵌套对象的对象,并希望按其中一个嵌套值排序(例如“month_sales”降序)。这是数据的样子:

{ 
"Bob": { sales: 13, revenue: 33, month_sales: 149 },
"Bill": { today_sales: 20, week_sales: 38, month_sales: 186 },
"Jane": { today_sales: 17, week_sales: 38, month_sales: 164 }
}

这就是我想要的样子(按month_sales降序排序):

{ 
"Bill": { today_sales: 20, week_sales: 38, month_sales: 186 },
"Jane": { today_sales: 17, week_sales: 38, month_sales: 164 }
"Bob": { sales: 13, revenue: 33, month_sales: 149 },
}

我查看了 Google 和 StackOverflow,只找到了几个处理对象排序而不是数组排序的答案,而且在每种情况下,答案都类似于“编写一个函数来转换对象”到一个数组,对其进行排序,然后将其转回一个对象。”

作为最后的手段,我愿意这样做,但似乎我应该能够做到这一点,而无需解构整个对象并将其重新组合在一起。也许有一种优雅的方式可以在 lodash 或其他东西中做到这一点?

【问题讨论】:

标签: javascript sorting lodash


【解决方案1】:

您只能拥有已排序的数组,而不能拥有对象。为此,您首先需要将您的对象映射 到一个数组。以下是使用 lodash map()sortBy() 的方法:

_(data)
    .map(function(value, key) {
        return _.defaults({ name: key }, value);
    })
    .sortBy('name')
    .value();
// →
// [
//   { name: "Bill", today_sales: 20, week_sales: 38, month_sales: 186 },
//   { name: "Bob", sales: 13, revenue: 33, month_sales: 149 },
//   { name: "Jane", today_sales: 17, week_sales: 38, month_sales: 164 }
// ]

映射使用defaults() 函数为每个数组项赋予一个新的name 属性,用于对数组进行排序。

【讨论】:

    【解决方案2】:

    这是不可能的,因为对象的属性在 javascript 中没有保证的顺序。您必须首先将其转换为数组:

    [ 
      { name: "Bob", sales: 13, revenue: 33, month_sales: 149 },
      { name: "Bill", today_sales: 20, week_sales: 38, month_sales: 186 },
      { name: "Jane", today_sales: 17, week_sales: 38, month_sales: 164 }
    ]
    

    然后,当您将其作为数组进行排序时,它将保持该顺序。

    【讨论】:

      【解决方案3】:

      如果将对象转换为数组,则可以像这样按类别对它们进行排序

      var arr = [ 
        { name: "Bob", sales: 13, revenue: 33, month_sales: 149 },
        { name: "Bill", today_sales: 20, week_sales: 38, month_sales: 186 },
        { name: "Jane", today_sales: 17, week_sales: 38, month_sales: 164 }
      ]
      
      arr.sort(function(x, y){
          var category = "month_sales"
          if (x[category] < y[category]) {
              return -1;
          }
          if (x[category] > y[category]) {
              return 1;
          }
          return 0;
      });
      

      【讨论】:

        【解决方案4】:

        虽然您无法对对象进行排序,但您可以创建一个按您想要的任何属性排序的索引,例如获取按 month_sales 从高到低排序的名称列表:

        var obj = { 
        "Bob": { sales: 13, revenue: 33, month_sales: 149 },
        "Bill": { today_sales: 20, week_sales: 38, month_sales: 186 },
        "Jane": { today_sales: 17, week_sales: 38, month_sales: 164 }
        }
        
        var index = Object.keys(obj).sort(function(a,b) {
                      return obj[b].month_sales - obj[a].month_sales;
                    });
        

        然后获取最高值的那个:

        console.log(index[0] + ':' + obj[index[0]].month_sales); // Bill:186
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2019-06-25
          • 1970-01-01
          • 2016-07-01
          • 1970-01-01
          • 1970-01-01
          • 2015-11-10
          • 2016-07-09
          相关资源
          最近更新 更多