我正在做我的一个前端项目,我有一种情况,我必须根据某些条件合并/添加阵列中存在的对象。条件是
所以我的输入是
[
{
label: 'label-1',
published: 1,
draft: 2,
id: 'some1'
},
{
label: 'label-1',
published: 2,
status: 0,
draft: 1,
id: 'some4'
},
{
label: 'label-2',
published: 1,
draft: 14,
id: 'some2'
},
{
label: 'label-2',
published: 12,
status: 0,
draft: 14,
id: 'some3'
}
]
和期待
[
{
label: 'label-1',
published: 3,
draft: 4,
status: 0
},
{
label: 'label-2',
published: 13,
draft: 28,
status: 0
}
]
目前我使用以下代码实现相同目的,但发现它并不整洁。有什么方法可以轻松实现这一点。
function mapData(data) {
let groupData = _.groupBy(data, 'label');
let stackBarData = [];
Object.keys(groupData).forEach((key) => {
if (groupData[key] && groupData[key].length > 0) {
let temp = Array.from(groupData[key]).reduce((a, b) => {
for (let property in b) {
if (b.hasOwnProperty(property)) {
if (property !== 'label' && property !== 'id' && property !== 'Others') {
a[property] = (a[property] || 0) + b[property];
} else {
a[property] = b[property];
}
}
}
return a;
}, {});
stackBarData.push(temp);
}
});
return stackBarData;
}

请帮忙。
答案 0 :(得分:2)
这是一个纯ES6函数,它根据唯一标签收集数字对象值,将它们添加起来(这就是你的行为):
function mapData(data) {
const grouped = new Map(data.map( ({label}) => [label, { label }] ));
for (let obj of data) {
let target = grouped.get(obj.label);
for (let [key, val] of Object.entries(obj)) {
if (typeof val === 'number') {
target[key] = (target[key] || 0) + val;
}
}
}
return [...grouped.values()];
}
// Sample data
const data = [{label: 'label-1',published: 1,draft: 2,id: 'some1'},{label: 'label-1',published: 2,status: 0,draft: 1,id: 'some4'},{label: 'label-2',published: 1,draft: 14,id: 'some2'},{label: 'label-2',published: 12,status: 0,draft: 14,id: 'some3'}];
console.log(mapData(data));
.as-console-wrapper { max-height: 100% !important; top: 0; }
如果您想要排除数字属性,那么拥有一组您感兴趣的显式属性可能会更好:
const props = new Set(['status', 'published', 'draft']);
// ... etc
//
if (props.has(key)) {
target[key] = (target[key] || 0) + val;
}
// ...
答案 1 :(得分:1)
<强> Lodash 强>
_.groupBy()
由标签,_.map()
组,并使用_.mergeWith()
合并每个组,_.omit()
id < / em>的。合并组时,如果当前值是数字,则将当前值和新值相加,如果不返回use FOS\RestBundle\Controller\Annotations as JMS;
- 如果定制器返回未定义,则由方法处理合并。
undefined
&#13;
const arr = [{"label":"label-1","published":1,"draft":2,"id":"some1"},{"label":"label-1","published":2,"status":0,"draft":1,"id":"some4"},{"label":"label-2","published":1,"draft":14,"id":"some2"},{"label":"label-2","published":12,"status":0,"draft":14,"id":"some3"}]
const result = _(arr)
.groupBy('label')
.map((g) => _.omit(_.mergeWith({}, ...g, (objValue, srcValue) => _.isNumber(objValue) ? objValue + srcValue : undefined), 'id'))
.value()
console.log(result)
&#13;
<强> ES6 强>
使用Array.reduce()
迭代数组。在每次迭代时检查累加器(Map)has 标签,如果没有添加带有标签的空对象作为键。使用keys迭代当前对象Array.forEach()
,忽略 id ,并对数值求和。要获得一个数组传播Map.values()
:
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>
&#13;