在javascript中对嵌套对象的对象进行排序(也许使用lodash?)

时间:2015-07-22 05:50:15

标签: javascript sorting lodash

我有一个嵌套对象的对象,并希望按其中一个嵌套值排序(例如“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或其他什么地方做到这一点?

4 个答案:

答案 0 :(得分:1)

这是不可能的,因为对象的属性在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 }
]

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

答案 1 :(得分: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 :(得分:0)

如果将对象转换为数组,则可以按类别

对其进行排序
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;
});

答案 3 :(得分:0)

虽然您无法对对象进行排序,但您可以根据所需的任何属性创建索引,例如:获取按 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