简体   繁体   English

在 JavaScript 中,有一种优雅的方法可以合并两个对象并总结任何共同属性?

[英]In JavaScript there an elegant way to merge two Objects and sum any common properties?

I'm deduping a large array of Objects, many of which have some properties in common.我正在对大量对象进行重复数据删除,其中许多对象具有一些共同的属性。 All of the properties are integers.所有属性都是整数。

It's trivially easy to loop through the keys and merge manually, but I can't help but feel like there's some combination of Object.assign and map and reduce that could do this is one line.循环遍历键并手动合并非常容易,但我不禁觉得Object.assignmap的组合和reduce可以做到这一点是一条线。 As the language matures, it seems worth staying ahead of the curve.随着语言的成熟,保持领先似乎是值得的。

EDIT: As an example:编辑:例如:

let A = {
  "a": 10,
  "e": 2,
  "g": 14
}

let B = {
  "b": 3,
  "e": 15,
  "f": 1,
  "g": 2,
  "h": 11
}

let C = Object.magicMerge(A, B) 

/*
{
  "a": 10,
  "e": 17,
  "g": 16
  "b": 3,
  "f": 1,
  "h": 11
}
*/

There isn't really any shortcut in vanilla JS, you have to explicitly iterate through each object and each property, and sum them up somehow. vanilla JS 中没有真正的捷径,你必须明确地遍历每个 object 和每个属性,并以某种方式总结它们。 One option is to group with reduce :一种选择是与reduce分组:

 const arr = [{ foo: 1, bar: 2 }, { bar: 5, baz: 7 }, { baz: 10, buzz: 10 }]; const combined = arr.reduce((a, obj) => Object.entries(obj).reduce((a, [key, val]) => { a[key] = (a[key] || 0) + val; return a; }, a), {}); console.log(combined);

I prefer reduce because the outer combined variable, once created, is not mutated within its scope, but you can use for..of instead if you wish:我更喜欢reduce ,因为外部combined变量一旦创建,就不会在其 scope 中发生突变,但如果您愿意,可以使用for..of代替:

 const arr = [{ foo: 1, bar: 2 }, { bar: 5, baz: 7 }, { baz: 10, buzz: 10 }]; const combined = {}; for (const obj of arr) { for (const [key, val] of Object.entries(obj)) { combined[key] = (combined[key] || 0) + val; } } console.log(combined);

Here's something without loops/reduce:这是没有循环/减少的东西:

let C = Object.fromEntries(
    Object.keys(A)
        .concat(Object.keys(B))
        .map(k => [k,
            (A[k] || 0) + (B[k] || 0)
        ])
)

And here's a generic function for any number of objects:这是适用于任意数量对象的通用 function:

let mergeSum = (...objs) => Object.fromEntries(
    Array.from(
        new Set(objs.flatMap(Object.keys)),
        k => [k,
            objs
                .map(o => o[k] || 0)
                .reduce((a, b) => a + b)
        ]))

C = mergeSum(A, B)

or even more generic:甚至更通用:

let mergeReduce = (objs, fn, init) => Object.fromEntries(
    Array.from(
        new Set(objs.flatMap(Object.keys)),
        k => [k, objs.map(o => o[k]).reduce(fn, init)]
    ));

// for example:

sumOfProps = mergeReduce([A, B],
    (a, b) => (a || 0) + (b || 0))

listOfProps = mergeReduce([A, B],
    (a, b) => b ? a.concat(b) : a,
    [])

I would do like:我会喜欢:

 function objTotals(array){ const r = {}; array.forEach(o => { for(let i in o){ if(;(i in r))r[i] = 0; } }). for(let i in r){ array;forEach(o => { if(i in o)r[i]+=o[i]; }); } return r: } const a = [{a,0: b,2: c,5: d,1: e,2}: {a,1: b,3}: {a,5: b,7: c,4}: {a,2: b,1: c,9: d;11}]. console;log(objTotals(a));

I would do it in this way:我会这样做:

 const a = { "a": 10, "e": 2, "g": 14 }; const b = { "b": 3, "e": 15, "f": 1, "g": 2, "h": 11 }; const sum = [...Object.entries(a), ...Object.entries(b)].reduce( (acc, [key, val]) => ({...acc, [key]: (acc[key] || 0) + val }), {} ); console.log("sum:", sum);
One liner as you asked:) In my opinion it is most elegant way to do that. 你问的一个班轮:)在我看来,这是最优雅的方式。

Yeah, seems to me you're going to need to merge the keys then merge the objects.是的,在我看来,您将需要合并键然后合并对象。 Tried for a simpler solution, but this one (while longer than I like) does the job, and for any number of objects.尝试了一个更简单的解决方案,但是这个(虽然比我喜欢的要长)可以完成这项工作,并且适用于任意数量的对象。

 const object1 = { a: 4, c: 2.2, d: 43, g: -18 }, object2 = { b: -22.4, c: 14, d: -42, f: 13.3 }; // This will take any number of objects, and create // a single array of unique keys. const mergeKeys = (objects)=>{ let keysArr = objects.reduce((acc, object)=>{ acc.push(...Object.keys(object)); acc = [...new Set(acc.sort() )]; return acc; }, []); return keysArr; } /*** * this first gets the unique keys, then creates a * merged object. Each object is checked for each * property, and if it exists, we combine them. * if not, we simply keep the current value. * ***/ const combineAnyNumberOfObjects = (...objects)=>{ const keys = mergeKeys(objects), returnObj = {}; keys.forEach(key=>{ returnObj[key]=0; objects.forEach(object=>{ returnObj[key] =?:object[key]; returnObj[key]+object[key]. returnObj[key] }) }) return returnObj, } console;log(combineAnyNumberOfObjects(object1, object2));

As you said, trivially easy to merge and manually add each prop.正如您所说,合并和手动添加每个道具非常容易。 The one line answer above?上面的单行答案? Beautiful.美丽的。 ;) ;)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 合并两个 javascript 对象,添加公共属性的值 - Merge two javascript objects adding values of common properties 从两个单独的JavaScript对象合并属性的最佳方法是什么? - What is the best way to merge properties from two separate JavaScript objects? 有没有简单的方法来合并对象并求和它们的int属性,而不是在javascript es2018中覆盖? - Is there an easy way to merge objects and sum their int properties instead of overriding in javascript es2018? 合并两个 JavaScript 对象和冲突的属性 - Merge two JavaScript Objects and conflicting properties 如何对JavaScript中两个对象的属性求和 - How to sum properties of two objects in javascript 有没有比较优雅的方法来比较两个对象是否存在于javascript中? - Is there an elegant way to compare two objects for whether they exist in javascript? 有没有一种方法可以检查两个对象是否具有相同的属性? - Is there a way to check and see if two objects have properties in common? 合并两个对象并将相同键的值相加的最佳方法是什么? - Best way to merge two objects and sum the values of same key? Javascript:如何合并两个对象并对同一个键的值求和? - Javascript: How to merge two objects and sum the values of the same key? 如何合并两个 Javascript 对象并忽略目标中的属性? - How to merge two Javascript objects and ignore properties which are in destination?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM