合并对象具有数组,并保留数组的两个值

时间:2017-09-23 05:12:56

标签: javascript jquery arrays

我有2个对象,并使用jQuery.extend函数组合它们。

john_5_years_ago = {
    name: "john",
    company: "google",
    languages: ["c++", "java"]
}

john_now = {
    name: "john",
    company: "facebook",
    nation: "US",
    languages: ["python", "java", "javascript"]
}

$.extend(true, {}, john_5_years_ago, john_now)

它会返回如下结果:

{
    name: "john",
    company: "facebook",
    nation: "US",
    languages: ["python", "java", "javascript"]
}

但是我预计languages数组的值应该合并,而不是被覆盖。预期的结果应该是这样的:

{
    name: "john",
    company: "facebook",
    nation: "US",
    languages: ["python", "java", "javascript", "c++"]
}

我会感激任何想法。

4 个答案:

答案 0 :(得分:1)

试试这个:

 <!DOCTYPE html>
 <html>
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
 <body>

   <p>Click the button to join two arrays.</p>

    <button onclick="myFunction()">Try it</button>

   <p id="demo"></p>

  <script>
    function myFunction() {

    john_5_years_ago = {
     name: "john",
     company: "google",
     languages: ["c++", "java"]
    }

 john_now = {
   name: "john",
   company: "facebook",
  nation: "US",
  languages: ["python", "java", "javascript"]
 }

 var children  = $.extend(true, {}, john_5_years_ago, john_now);
  console.log(children)
  children = merge_array(children.languages, john_5_years_ago.languages);
  document.getElementById("demo").innerHTML = children;
}

function merge_array(array1, array2) {
  var result_array = [];
  var arr = array1.concat(array2);
  var len = arr.length;
  var assoc = {};
    while(len--) {
      var item = arr[len];
        if(!assoc[item]) 
       { 
         result_array.unshift(item);
         assoc[item] = true;
      }
   }

  return result_array;
 } </script>

</body>
 </html>

答案 1 :(得分:1)

jQuery.extend()将合并对象,深度也将起作用。但是,虽然合并数组的大小不会改变,但它不会找到明显的值。它将在索引处替换这些值,这就是它的作用(我已经包含了下面的描述演示)。

有关详细信息,请参阅document以及jQuery code

所以这个函数不会为你的情况提供解决方案,你应该编写一个自定义函数(比如我的解决方案部分)。

要将深度合并的结果存储在输出中,您应该在第二个参数中指定它,如$.extend(true, john_now, john_5_years_ago);

var john_5_years_ago = {
  name: "john",
  company: "google",
  languages: ["c++", "javascript", "c"],
  extra: {
    aExtra: "aExtra1 value",
    bExtra: "bExtra1 value",
    cExtra: "cExtra1 value"
  }
}

var john_now = {
  name: "john",
  company: "facebook",
  nation: "US",
  languages: ["python", "java", "c", "javascript"],
  extra: {
    aExtra: "aExtra2 value",
    cExtra: "cExtra2 value",
    zExtra: "zExtra2 value"
  }
}

$.extend(true, john_now, john_5_years_ago);
console.log(john_now);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

解决方案:

使用自定义函数循环遍历这两个对象以深入合并两个对象。

注意: -

我还添加了deep参数来指定是否应该在子级别复制对象。

var john_5_years_ago = {
  name: "john",
  company: "google",
  languages: ["c++", "java"],
  extra: {aExtra:"aExtra1 value", bExtra: "bExtra1 value", cExtra: "cExtra1 value"}
}

var john_now = {
  name: "john",
  company: "facebook",
  nation: "US",
  languages: ["python", "java", "javascript"],
  extra: {aExtra:"aExtra2 value", cExtra: "cExtra2 value", zExtra: "zExtra2 value"}
}

function extend(object1, object2, deep) {
  $.each(object1, function(i, key) {
    if (object1[i] instanceof Array && object2[i] instanceof Array) {
      $.each(object2[i], function(j) {
        if (object1[i].indexOf(object2[i][j]) == -1)
          object1[i].push(object2[i][j])
      });
    }else if(deep === true && object1[i].constructor==={}.constructor && object2[i].constructor==={}.constructor){
    //console.log('{}');
      extend(object1[i], object2[i]);
    } else if(object2[i] != undefined) {
      object1[i] = object2[i];
    }
  });
  $.each(object2, function(j) {
    if (object1[j] === undefined)
      object1[j] = object2[j];
  });
}
extend(john_now, john_5_years_ago, true);
console.log(john_now);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

答案 2 :(得分:0)

你可以在Plain JS中写这个:

&#13;
&#13;
var old = {
    name: "john",
    company: "google",
    languages: ["c++", "java"]
}

var now = {
    name: "john",
    company: "facebook",
    nation: "US",
    languages: ["python", "java", "javascript"]
}

Object.keys(old).forEach(function(prop) {
  if(now[prop] != undefined) {
    if(now["languages"] instanceof Array && old[prop] instanceof Array) {
      old[prop].forEach(function(item) {
        if(now[prop].indexOf(item) == -1) {
          now[prop].push(item);
        }
      });
    }
  } else {
    now[prop] = old[prop];
  }
});

console.log(now);
&#13;
&#13;
&#13;

答案 3 :(得分:0)

您可以使用解决方案https://jsfiddle.net/6c5kgwcw/

&#13;
&#13;
var john_5_years_ago = {
    name: "john",
    company: "google",
    languages: ["c++", "java"]
}

var john_now = {
    name: "john",
    company: "facebook",
    nation: "US",
    languages: ["python", "java", "javascript"]
}

$.each(john_now, function(i, key){
  if(i === 'languages'){
    $.each(john_5_years_ago[i], function(j){
      if(john_now[i].indexOf(john_5_years_ago[i][j]) == -1)
    	john_now[i].push(john_5_years_ago[i][j])	
    });
  }
});

console.log(john_now);
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
&#13;
&#13;
&#13;

我使用了jQuery .each方法&amp;循环遍历新对象。

希望这会对你有所帮助。