我正在做我的前端项目之一,我有一种情况,我必须合并/添加对象在数组中存在的一些条件。条件是
所以我的意见是
[
{
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;
}
请帮帮忙。
发布于 2018-02-02 16:00:48
下面是一个纯粹的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;
}
// ...发布于 2018-02-02 16:15:18
Lodash
_.groupBy()的标签,_.map()组,并合并每个组使用_.mergeWith(),和_.omit()的id。合并组时,如果当前值是数字,则将当前值和新值之和,如果不返回undefined --如果自定义程序返回未定义的值,则由方法处理合并。
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)<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>
ES6
使用Array.reduce()迭代数组。在每次迭代中,检查累加器( 地图)是否将标签标记为有,如果没有,则添加一个带有标签作为键的空对象。使用关键字迭代当前对象Array.forEach(),忽略id,并对数值进行求和。以获得一个扩展Map.values()的数组
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.reduce((m, o) => {
m.has(o.label) || m.set(o.label, {})
const obj = m.get(o.label)
Object.keys(o).forEach((k) => {
if(k === 'id') return
obj[k] = typeof o[k] === 'number' ? (obj[k] || 0) + o[k] : o[k]
})
return m
}, new Map()).values()]
console.log(result)
https://stackoverflow.com/questions/48585817
复制相似问题