[英]lodash grouping an array by multiple keys
[Update]: I've removed most of the layout and lodash (failed code) from before because the JSON data format has changed. [更新]:由于JSON数据格式已更改,因此我从之前删除了大多数布局和lodash(失败的代码)。
I'm trying to group a data set in preparation for aggregating totals. 我正在尝试对数据集进行分组,以准备总计。 Here is the incoming JSON layout.
这是传入的JSON布局。 I need to group by country, then by brand:
我需要按国家/地区分组,然后按品牌分组:
[
{
$id: "1",
countryCode: "HT",
brand: "CO",
roomNights: 12,
hotelSpend: 2000
},
{
$id: "2",
countryCode: "PK",
brand: "HH",
roomNights: 201,
hotelSpend: 10000
},
{
$id: "3",
countryCode: "RO",
brand: "CO",
roomNights: 34,
hotelSpend: 5000
},
{
$id: "4",
countryCode: "US",
brand: "ES",
roomNights: 120,
hotelSpend: 56000
},
{
$id: "5",
countryCode: "PK",
brand: "HH",
roomNights: 145,
hotelSpend: 33000
}
]
The data needs to be transformed into this format: 数据需要转换为以下格式:
['Brand','HT' , 'PK' , 'US' , 'RO', 'Avg Rm', 'Avg Spend']
['HH' ,'0/0' ,'201/10000', '0/0' , '0/0' , 201, 10000],
['CO' ,'12/2000','0/0', , '0/0' , '34/5000', 23 , 3500],
['ES' , '0/0' ,'0/0' , '120/50000' , '0/0' , 120, 50000]
The roomNights and hotelSpend will be totalled per brand & country and the average of each will need to be calculated fields at the end. 每个品牌和国家/地区的roomNights和hotelSpend总计,最后需要计算每个字段的平均值。
Thanks! 谢谢!
Let's first define a mean
function and add it to _
: 首先定义一个
mean
函数并将其添加到_
:
_.mixin({
mean: function(ds) {
return _(ds).foldr(function(a, b) { return a + b; }, 0) / ds.length;
}
});
Let's define functions for selecting the rows and columns: 让我们定义用于选择行和列的函数:
var row = function(d) { return d.brand; };
var col = function(d) { return d.countryCode; };
aggr
function takes a sub-list of our data and aggregates its values into one value (which here is a string representation of a rational number): aggr
函数获取数据的子列表并将其值聚合为一个值(这里是有理数的字符串表示形式):
var aggr = function(ds) {
var val = _(ds).foldr(function(a, b) {
return {
roomNights: a.roomNights + b.roomNights,
hotelSpend: a.hotelSpend + b.hotelSpend
};
}, {roomNights: 0, hotelSpend: 0});
return val.roomNights + "/" + val.hotelSpend;
};
Our rows and columns labels: 我们的行和列标签:
rows = _.chain(data).map(row).unique().value();
columns = _.chain(data).map(col).unique().value();
The pivot: 枢纽:
[["Brand/Country"].concat(columns).concat(["Avg Rm", "Avg Spend"])] // header row
.concat(_(rows).map(function(r){
// data in this row
rdata = _(data).filter(function(d) { return row(d) == r; });
return [r].concat(_(columns).map(function(c){
return aggr(_(rdata).filter(function(d) {return col(d) == c; }));
}))
// the last two columns in each row
.concat([
_.chain(rdata).map(function(d) { return d.roomNights; }).mean().value(),
_.chain(rdata).map(function(d) { return d.hotelSpend; }).mean().value()
]);
}));
You can control the order or filter the result by specific countryCode
or brand
by modifying the rows
and columns
arrays, similar to spreadsheets. 您可以通过修改
rows
和columns
数组(类似于电子表格)来控制订单或通过特定的countryCode
或brand
过滤结果。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.