合并两个对象而不覆盖

时间:2015-09-17 23:09:04

标签: javascript

我有两个类似的Javascript对象:

"Object 1": {
    "a": {
        "1": "test 1",
        "2": "test 2"
    },
    "b": {
        "3": "test 3",
        "4": "test 4"
    },
}

"Object 2": {
    "a": {
        "1": "test 5",
        "2": "test 6"
    },
    "b": {
        "3": "test 7",
        "4": "test 8"
    },
}

两者之间的唯一区别是最深层次的值。我想合并它们,因此生成的对象如下所示:

"Object 4": {
    "a": {
        "1": ["test 1", "test 5"],
        "2": ["test 2", "test 6"]
    },
    "b": {
        "3": ["test 3", "test 7"],
        "4": ["test 4", "test 8"]
    },
}

基本上我只想将最深层的值组合到列表中。有人可以帮忙吗?

编辑:我的最终目标是将这些值吐出到这样的表中:

<table>
    <tr>
        <td>test 1</td>
        <td test 5</td>
    </tr>
    <tr>
        <td>test 2</td>
        <td test 6</td>
    </tr>
    <tr>
        <td>test 3</td>
        <td test 7</td>
    </tr>
    <tr>
        <td>test 4</td>
        <td test 8</td>
    </tr>
</table>

如果您知道更好的方法,请告诉我们!

3 个答案:

答案 0 :(得分:4)

&#13;
&#13;
var o = {
  1: {
    "a": { "1": "test 1", "2": "test 2" },
    "b": { "3": "test 3", "4": "test 4" },
  }, 2: {
    "a": { "1": "test 5", "2": "test 6" },
    "b": { "3": "test 7", "4": "test 8" },
  }
}

function mergeObject (base, toMerge) {
  // loop through the keys in the item to be merged (`toMerge`)
  for (var key in toMerge) {
    // if `base[key]` is not already an object, set it as one
    base[key] = base[key] || {}
    // look through the keys in `toMerge[key]`
    for (var k in toMerge[key]) {
      // if the base already has an array at `base[key][k]`
      if (Array.isArray(base[key][k])) {
        // then push the current element
        base[key][k].push(toMerge[key][k])
      } else {
        // otherwise, create an array and set `toMerge[key][k]` as the first element
        base[key][k] = [toMerge[key][k]]
      }
    }
  }
  return base
}

function merge (o1, o2) {
  return mergeObject(mergeObject({}, o1), o2)
}

document.write(JSON.stringify(merge(o[1], o[2])))
&#13;
&#13;
&#13;

答案 1 :(得分:3)

我会使用underscore.js。此例程适用于两棵树中的叶子值到任何级别,而不仅仅是第二级深度。

function is_object_only(v)
{
  //_.isObject() returns true for functions and Arrays. But this predicate only returns true for objects
  return _.isObject(v) && !_.isFunction(v) && !_.isArray(v)
}

function concat_leaf_values(obj_1, obj_2)
{
  var result = {}
  var all_keys = _.union(_.keys(obj_1), _.keys(obj_2))
  _.each(all_keys, function(key)
  {
    var new_val
    var v1 = obj_1[key]
    var v2 = obj_2[key]
    if(is_object_only(v1) && is_object_only(v2))
    {
      new_val = concat_leaf_values(v1, v2) //recurse
    }
    else
    {
      new_val = _.compact([].concat(v1).concat(v2)) 
      // if either v1 or v2 is an array, they will be concatenated on, not nested.  
      // and we are stripping any undefined/null values in case v1 or v2 don't exist.
      // if you intentionally want arrays with null/undefined in your tree, then this clause 
      // should be changed
    }
    result[key] = new_val
  })
  return result
}

//concat_leaf_values({a:{a:1, b:2}, b:5}, {a:{a:10, b:20}, b:50}) => {"a":{"a":[1,10],"b":[2,20]},"b":[5,50]}
<script src="http://underscorejs.org/underscore-min.js"></script>

答案 2 :(得分:0)

您可以使用下划线map

以下是摘录:

_.map(object1, function(val, key){
  if(object2[key] != undefined) {
    _.map(val, function(val1, key1){
        if(object2[key][key1] != undefined){
            val[key1] = val1  + "," + object2[key][key1];
        }
    });
  }
});