2017-09-23 144 views
4

我有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++"] 
} 

我会感激任何想法。

回答

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>

解决方法:

通过这些

使用自定义功能进行循环2个对象,用于深度合并两个对象。

注: -

我还添加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>

+1

谢谢,你解释给我一个线索。我发现了其他解决方案,有点棘手。我通过在第243行后面添加'copy = _.union(src,copy)'来重新实现函数'jQuery.extend''。就是这样,'jQuery.extend'可以工作! – LittleZero

+0

多数民众赞成在...欢迎:) – jafarbtech

0

你可以在纯JS写:

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);

0

在这里,你去了一个解决方案https://jsfiddle.net/6c5kgwcw/

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) 
 
    \t john_now[i].push(john_5_years_ago[i][j]) \t 
 
    }); 
 
    } 
 
}); 
 

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

我用jQuery .each方法&通过新的对象循环。

希望这会帮助你。

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>