我需要将一些数据转换为特殊格式。棘手的部分是,它需要通过动态键进行分组和嵌套。由于原始数据是平坦的。
这是一些简化的示例数据:
const data = [
{
category: 'Classic',
price: 1,
order: '1233-ABC'
currency: 'EUR',
},
{
category: 'Classic',
price: 2,
order: '1234-ABC'
currency: 'EUR',
},
{
category: 'Modern',
price: 3,
order: '1235-ABC'
currency: 'USD',
},
{
category: 'Classic',
price: 4,
order: '1236-ABC'
currency: 'EUR',
},
{
category: 'Modern',
price: 5,
order: '1237-ABC'
currency: 'EUR',
},
{
category: 'Classic',
price: 6,
order: '1238-ABC'
currency: 'USD',
},
{
category: 'Modern',
price: 7,
order: '1239-ABC'
currency: 'USD',
}
];
现在,我要定义分组和聚合。
例如:
grouping = ['category'];
sum = ['price'];
因此,应按关键字分组category
并汇总所有price
关键字条目。
//预期输出
[{
category: 'Classic',
price: 13
}, {
category: 'Modern',
price: 15
}]
我通过减少工作。
这是代码:
let groupingsField = ['category'];
let aggregateField = ['price']
let [group, ...rest] = groupingsField
let [sum, ...noone] = aggregateField
const groupedData = data.reduce((acc, current) => {
acc.push({
[group]: current[group],
[sum]: data.filter(item => item[group] === current[group])
.map(el => el[sum])
.reduce((total, current) => total + current)
})
return acc
}, [])
.reduce((acc, current) => {
const x = acc.find(item => item[group] === current[group])
return !x ? acc.concat([current]) : acc
}, [])
但是,我需要分组是动态的,并且如果那里存在大于1的值,它将创建嵌套的sub
数据集。应该可以添加多个分组。
//示例2
grouping = ['category', 'currency'];
sum = ['price'];
//预期输出
[{
category: 'Classic',
price: 13,
sub: [{
currency: 'EUR',
price: 7
}, {
currency: 'USD',
price: 6
}]
}, {
category: 'Modern',
price: 15,
sub: [{
currency: 'EUR',
price: 9
}, {
currency: 'USD',
price: 10
}]
}]
因此,如果我要向分组添加另一个键
grouping = ['category', 'currency', 'something'];
它应该是三个级别的深层嵌套。
{
category: 'Modern',
price: 15,
sub: [{
currency: 'EUR',
price: 9,
sub: [{
someting: ...
price: ...
}]
}]
}
但是,我无法解决这个问题,如何基于来动态添加嵌套groupings
。我想我需要在这里递归。
希望对此有所帮助!
谢谢您的帮助!但是,经过一番睡眠,我想出了自己的解决方案:
groups = ['category', 'currency']; // this can be dynamic
sum = ['price'];
function createGroup (groups, data, sum, childNode = 'sub') {
let [primaryGroup, ...rest] = groups;
let groupedData = data.reduce((acc, current) => {
let chunk = {
[primaryGroup]: current[primaryGroup],
[sum]: data.filter(item => item[primaryGroup] === current[primaryGroup])
.map(el => el[sum])
.reduce((total, current) => total + current),
...(rest.length > 0 ? {[childNode]: createGroup(rest, data)} : {})
}
acc.push(chunk)
return acc
}, [])
.reduce((acc, current) => {
const x = acc.find(item => item[primaryGroup] === current[primaryGroup])
return !x ? acc.concat([current]) : acc
}, [])
return groupedData;
}
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句