在 javascript 中对嵌套对象的对象进行排序(可能使用 lodash?)
Sorting an object of nested objects in javascript (maybe using 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 和 Whosebug,只找到了几个处理对象排序而不是数组排序的答案,并且在每种情况下答案都是 "write a function to convert the object to an array, sort that, and then turn it back into an object."
作为最后的手段,我愿意这样做,但似乎我应该能够做到这一点,而无需解构整个对象并将其重新组合在一起。也许有一种优雅的方法可以在 lodash 或其他东西中做到这一点?
这是不可能的,因为对象的属性在 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 }
]
然后,当您将其作为数组进行排序时,它将保持该顺序。
如果将对象转换为数组,则可以像这样按类别对它们进行排序
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;
});
虽然您无法对对象进行排序,但您可以创建一个索引,根据您想要的 属性 进行排序,例如获取按 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
只能排序数组,不能排序对象。为此,您首先需要将您的对象 map 到一个数组。以下是使用 lodash map() and 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
属性,用来对数组进行排序
我有一个嵌套对象的对象,想按嵌套值之一排序(例如 "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 和 Whosebug,只找到了几个处理对象排序而不是数组排序的答案,并且在每种情况下答案都是 "write a function to convert the object to an array, sort that, and then turn it back into an object."
作为最后的手段,我愿意这样做,但似乎我应该能够做到这一点,而无需解构整个对象并将其重新组合在一起。也许有一种优雅的方法可以在 lodash 或其他东西中做到这一点?
这是不可能的,因为对象的属性在 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 }
]
然后,当您将其作为数组进行排序时,它将保持该顺序。
如果将对象转换为数组,则可以像这样按类别对它们进行排序
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;
});
虽然您无法对对象进行排序,但您可以创建一个索引,根据您想要的 属性 进行排序,例如获取按 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
只能排序数组,不能排序对象。为此,您首先需要将您的对象 map 到一个数组。以下是使用 lodash map() and 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
属性,用来对数组进行排序