减少多维数组
Reduce Multi Dimensional Array
我目前正在尝试映射和缩减函数以展平多维数组。
这是一个模拟示例数据集:
data: [
{
label: "Sort-01"
data: [
{
label: "OCT-2017"
weight: 2304
},
{
label: "NOV-2017"
weight: 1783
}
]
},
{
label: "Sort-02"
data: [
{
label: "OCT-2017"
weight: 4785
},
{
label: "NOV-2017"
weight: 102
}
]
},
......
]
我知道为了按排序编号进行 map-reduce,我可以使用:
data.map(sort => sort.data.reduce((a,b) => a.weight + b.weight));
但是,我想按月减少而不是排序数。
我将不胜感激任何帮助。
谢谢,
周杰伦
使用 Array#map 获取 data
属性数组的数组,然后用 Array#concat and spread. Use Array#reduce to collect the values into a Map, then use Map#values 展平,然后使用扩展语法转换回数组:
const array = [{"label":"Sort-01","data":[{"label":"OCT-2017","weight":2304},{"label":"NOV-2017","weight":1783}]},{"label":"Sort-02","data":[{"label":"OCT-2017","weight":4785},{"label":"NOV-2017","weight":102}]}];
const result = [... // spread the values iterator to an array
[].concat(...array.map(({ data }) => data)) // map the array into an array of data arrays
.reduce((m, { label, weight }) => {
// take item if label exists in map, if not create new
const item = m.get(label) || { label, weight: 0 };
item.weight += weight; // add the weight
return m.set(label, item); // set the item in the map
}, new Map).values()] // get the values iterator
console.log(result);
这是一个无传播版本:
const array = [{"label":"Sort-01","data":[{"label":"OCT-2017","weight":2304},{"label":"NOV-2017","weight":1783}]},{"label":"Sort-02","data":[{"label":"OCT-2017","weight":4785},{"label":"NOV-2017","weight":102}]}];
const helper = Object.create(null);
const result = [].concat.apply([], array.map(({ data }) => data)) // map the array into an array of data arrays, and flatten by apply concat
.reduce((r, { label, weight }) => {
// if label is not in helper, add to helper, and push to r
if(!helper[label]) {
helper[label] = { label, weight: 0 };
r.push(helper[label]);
}
helper[label].weight += weight; // add the weight to the object
return r;
}, []) // get the values iterator
console.log(result);
您可以使用 reduce 或 来获得扁平化的数据数组。从那里将您的年份标签重新分配为键,将权重重新分配为值。
然后传递给另一个减速器,以便按月计算总重量。
const data = [{label: "Sort-01",data: [{label: "OCT-2017",weight: 2304,},{label: "NOV-2017",weight: 1783,},],},{label: "Sort-02",data: [{label: "OCT-2017",weight: 4785,},{label: "NOV-2017",weight: 102,},],},];
const flatten = (acc, cur) => {
cur.data.forEach(val => acc.push(val));
return acc;
};
const monthMap = ({ label, weight }) => ({ [label]: weight });
const reducer = (acc, cur) => {
const key = Object.keys(cur)[0]
if (!acc.hasOwnProperty(key)) { acc[key] = 0 }
acc[key] += cur[key];
return acc;
};
let x = data.reduce(flatten, []).map(monthMap).reduce(reducer, {});
console.log(x);
我目前正在尝试映射和缩减函数以展平多维数组。
这是一个模拟示例数据集:
data: [
{
label: "Sort-01"
data: [
{
label: "OCT-2017"
weight: 2304
},
{
label: "NOV-2017"
weight: 1783
}
]
},
{
label: "Sort-02"
data: [
{
label: "OCT-2017"
weight: 4785
},
{
label: "NOV-2017"
weight: 102
}
]
},
......
]
我知道为了按排序编号进行 map-reduce,我可以使用:
data.map(sort => sort.data.reduce((a,b) => a.weight + b.weight));
但是,我想按月减少而不是排序数。
我将不胜感激任何帮助。
谢谢,
周杰伦
使用 Array#map 获取 data
属性数组的数组,然后用 Array#concat and spread. Use Array#reduce to collect the values into a Map, then use Map#values 展平,然后使用扩展语法转换回数组:
const array = [{"label":"Sort-01","data":[{"label":"OCT-2017","weight":2304},{"label":"NOV-2017","weight":1783}]},{"label":"Sort-02","data":[{"label":"OCT-2017","weight":4785},{"label":"NOV-2017","weight":102}]}];
const result = [... // spread the values iterator to an array
[].concat(...array.map(({ data }) => data)) // map the array into an array of data arrays
.reduce((m, { label, weight }) => {
// take item if label exists in map, if not create new
const item = m.get(label) || { label, weight: 0 };
item.weight += weight; // add the weight
return m.set(label, item); // set the item in the map
}, new Map).values()] // get the values iterator
console.log(result);
这是一个无传播版本:
const array = [{"label":"Sort-01","data":[{"label":"OCT-2017","weight":2304},{"label":"NOV-2017","weight":1783}]},{"label":"Sort-02","data":[{"label":"OCT-2017","weight":4785},{"label":"NOV-2017","weight":102}]}];
const helper = Object.create(null);
const result = [].concat.apply([], array.map(({ data }) => data)) // map the array into an array of data arrays, and flatten by apply concat
.reduce((r, { label, weight }) => {
// if label is not in helper, add to helper, and push to r
if(!helper[label]) {
helper[label] = { label, weight: 0 };
r.push(helper[label]);
}
helper[label].weight += weight; // add the weight to the object
return r;
}, []) // get the values iterator
console.log(result);
您可以使用 reduce 或
const data = [{label: "Sort-01",data: [{label: "OCT-2017",weight: 2304,},{label: "NOV-2017",weight: 1783,},],},{label: "Sort-02",data: [{label: "OCT-2017",weight: 4785,},{label: "NOV-2017",weight: 102,},],},];
const flatten = (acc, cur) => {
cur.data.forEach(val => acc.push(val));
return acc;
};
const monthMap = ({ label, weight }) => ({ [label]: weight });
const reducer = (acc, cur) => {
const key = Object.keys(cur)[0]
if (!acc.hasOwnProperty(key)) { acc[key] = 0 }
acc[key] += cur[key];
return acc;
};
let x = data.reduce(flatten, []).map(monthMap).reduce(reducer, {});
console.log(x);