如何通过键合并两个对象值

Ven*_*kat 31 javascript jquery

试图查看是否有任何javascript库功能可以合并两个json对象的特定键的值

var x ={ "student-marks":{'math':1,'physics':5} };
var y ={ "student-marks":{'chemistry':3,'history':2} };
Run Code Online (Sandbox Code Playgroud)

使用$ .extend和$ .merge给出以下结果

$.extend({},x,y)  leads to  { "student-marks":{'chemistry':3,'history':2} }

$.merge(x,y) leads to { "student-marks":{'math':1,'physics':2} }
Run Code Online (Sandbox Code Playgroud)

我在寻找的是什么{ "student-marks":{'math':1,'physics':5, 'chemistry':3,'history':2} }?

Tha*_*you 37

你想深入扩展

$.extend(true, {}, x, y);
Run Code Online (Sandbox Code Playgroud)

查看jQuery.extend([ deep ],target,object1 [,objectN ])的文档

  • 与lodash或下划线相似的解决方案是什么?我有几乎相同的问题,但是不使用jQuery并且更喜欢lodash实现_.merge?这是我问:http://stackoverflow.com/questions/23186187/merge-two-javascript-objects-if-key-value-is-equal (2认同)

shi*_*xis 12

不依赖jQuery的简单javascript函数将帮助您合并两个具有嵌套对象的JSON对象.

function mergeJSON(source1,source2){
    /*
     * Properties from the Souce1 object will be copied to Source2 Object.
     * Note: This method will return a new merged object, Source1 and Source2 original values will not be replaced.
     * */
    var mergedJSON = Object.create(source2);// Copying Source2 to a new Object

    for (var attrname in source1) {
        if(mergedJSON.hasOwnProperty(attrname)) {
          if ( source1[attrname]!=null && source1[attrname].constructor==Object ) {
              /*
               * Recursive call if the property is an object,
               * Iterate the object and set all properties of the inner object.
              */
              mergedJSON[attrname] = mergeJSON(source1[attrname], mergedJSON[attrname]);
          } 

        } else {//else copy the property from source1
            mergedJSON[attrname] = source1[attrname];

        }
      }

      return mergedJSON;
}
Run Code Online (Sandbox Code Playgroud)

  • 此解决方案在NodeJS中不起作用.不得不安装https://www.npmjs.com/package/extend. (2认同)
  • 还在等你@andrewlorien (2认同)

Thi*_*ata 5

ES2018 中的新展开运算符提供了一些很好的方法来做到这一点:

function combine(...list){
  return list.reduce(
     (a,b)=>{
       return {...a,...b}
     }
  )
}

// work as expected with simple objects
console.log(
  combine(
    {x:3,z:1},
    {x:4,m:4},
    {a:1},
    {b:2}
));

// is not a good recursive solution
console.log(
  combine(
    {x:3,z:1,child:{c:1}},
    {x:4,m:4,child:{d:3}},
    {a:1},
    {b:2}
));
Run Code Online (Sandbox Code Playgroud)

这是我能得到的最好的递归解决方案

function combine_recursive(...list) {    
    return list.reduce(
        (a,b) => {
            // for non objects return b if exists or a
            if ( ! ( a instanceof Object ) || ! ( b instanceof Object ) ) {
                return b !== undefined ? b : a;
            }
            // for objects, get the keys and combine them
            const keys = Object.keys(a).concat(Object.keys(b));
            return keys.map(
                key => { 
                    return  {[key]: combine_recursive(a[key],b[key])}
                }
            ).reduce(
                (x,y) => {
                    return {...x,...y}
                }
            );
        }
    )
}
   
// testing recursive and the priority
console.log(
  combine_recursive(
    {x:3,z:1,child:{c:1,k:1}},
    {x:4,m:4,child:{d:3,k:2}},
    {a:1},
    {b:2}
));
 
// using the example of the question
var x ={ "student-marks":{'math':1,'physics':5} };
var y ={ "student-marks":{'chemistry':3,'history':2} };
console.log( combine_recursive(x,y) );
Run Code Online (Sandbox Code Playgroud)