Cách tốt nhất / tiêu chuẩn để hợp nhất hai mảng kết hợp trong JavaScript là gì? Có phải tất cả mọi người chỉ làm điều đó bằng cách lăn for
vòng lặp của riêng mình ?
Cách tốt nhất / tiêu chuẩn để hợp nhất hai mảng kết hợp trong JavaScript là gì? Có phải tất cả mọi người chỉ làm điều đó bằng cách lăn for
vòng lặp của riêng mình ?
Câu trả lời:
với jquery bạn có thể gọi $.extend
var obj1 = {a: 1, b: 2};
var obj2 = {a: 4, c: 110};
var obj3 = $.extend(obj1, obj2);
obj1 == obj3 == {a: 4, b: 2, c: 110} // Pseudo JS
(PGS. mảng là đối tượng trong js)
xem tại đây: http://api.jquery.com/jQuery.extend/
chỉnh sửa: Giống như rymo đề xuất, tốt hơn là làm theo cách này:
obj3 = $.extend({}, obj1, obj2);
obj3 == {a: 4, b: 2, c: 110}
Như ở đây obj1 (và obj2) vẫn không thay đổi.
chỉnh sửa2: Năm 2018 cách thực hiện là thông qua Object.assign
:
var obj3 = Object.assign({}, obj1, obj2);
obj3 === {a: 4, b: 2, c: 110} // Pseudo JS
Nếu làm việc với ES6, điều này có thể đạt được với Toán tử trải rộng :
const obj3 = { ...obj1, ...obj2 };
obj1
, sử dụng một đối tượng trống làm mục tiêu:$.extend({}, obj1, obj2)
Object.assign()
, điều này không phụ thuộc vào JQuery nếu bạn chưa sử dụng thư viện.
Bây giờ trong năm 2016 tôi sẽ nói cách tốt nhất / tiêu chuẩn là Object.assign ()
Pure Javascript. Không cần jQuery.
obj1 = {a: 1, b: 2};
obj2 = {a: 4, c: 110};
obj3 = Object.assign({},obj1, obj2); // Object {a: 4, b: 2, c: 110}
Thêm thông tin, ví dụ và polyfill tại đây:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign
Đây là cách Prototype thực hiện:
Object.extend = function(destination, source) {
for (var property in source) {
if (source.hasOwnProperty(property)) {
destination[property] = source[property];
}
}
return destination;
};
được gọi là, ví dụ:
var arr1 = { robert: "bobby", john: "jack" };
var arr2 = { elizabeth: "liz", jennifer: "jen" };
var shortnames = Object.extend(arr1,arr2);
EDIT : đã thêm hasOwnProperty () kiểm tra như được chỉ ra chính xác bởi bucabay trong các nhận xét
Giữ cho nó đơn giản ...
function mergeArray(array1,array2) {
for(item in array1) {
array2[item] = array1[item];
}
return array2;
}
arrau1.prototype
hasOwnProperty
kiểm tra. Việc đề cập đến các đối tượng là các mảng cũng gây hiểu nhầm (chúng là các đối tượng), các tên arg sẽ truyền tải rằng mảng2 bị đột biến hoặc một đối tượng mới sẽ được trả về. Tôi sẽ chỉnh sửa câu trả lời nhưng thực tế nó sẽ trở thành gần như chính xác câu trả lời đã được chỉnh sửa của Jonathan Fingerland đã được sửa.
Underscore cũng có một phương thức mở rộng:
Sao chép tất cả các thuộc tính trong các đối tượng nguồn sang đối tượng đích. Đó là theo thứ tự, vì vậy nguồn cuối cùng sẽ ghi đè các thuộc tính cùng tên trong các đối số trước đó.
_.extend(destination, *sources)
_.extend({name : 'moe'}, {age : 50});
=> {name : 'moe', age : 50}
Trong võ đường , "hợp nhất" 2 đối tượng / mảng sẽ là lang.mixin(destination, source)
- bạn cũng có thể trộn nhiều nguồn vào một đích, v.v. - xem tham chiếu của hàm mixin để biết chi tiết.
Bạn có muốn ghi đè lên một thuộc tính nếu tên giống nhau nhưng giá trị không?
Và bạn có muốn thay đổi vĩnh viễn một trong các đối tượng ban đầu không,
hoặc bạn muốn một đối tượng hợp nhất mới được trả lại?
function mergedObject(obj1, obj2, force){
for(var p in obj1) this[p]= obj1[p];
for(var p in obj2){
if(obj2.hasOwnProperty(p)){
if(force || this[p]=== undefined) this[p]= obj2[p];
else{
n= 2;
while(this[p+n]!== undefined)++n;
this[p+n]= obj2[p];
}
}
}
}
function extend(objects) {
var args
, first = Array.prototype.slice.call(arguments, 0, 1)[0]
, second;
if (arguments.length > 1) {
second = Array.prototype.splice.call(arguments, 1, 1)[0];
for (var key in second) {
first[key] = second[key];
}
args = Array.prototype.slice.call(arguments, 0);
return extend.apply(this, args);
}
return first;
}
...
var briansDirections = {
step1: 'Remove pastry from wrapper.',
step2: 'Place pastry toaster.',
step3: 'Remove pastry from toaster and enjoy.',
};
extend(briansDirections, { step1: 'Toast Poptarts' }, { step2: 'Go ahead, toast \'em' }, { step3: 'Hey, are you sill reading this???' });
...
Điều này chỉ đơn giản là mở rộng một biểu tượng của các đối tượng, đệ quy. Ngoài ra, lưu ý rằng chức năng đệ quy này là TCO ( Tối ưu hóa cuộc gọi đuôi ) vì sự trở lại của nó là cuộc gọi cuối cùng với chính nó.
Ngoài ra, bạn có thể muốn các thuộc tính được nhắm mục tiêu . Trong trường hợp này, bạn có thể muốn ngưng tụ đối tượng dựa trên id
, quantity
hoặc tài sản khác. Cách tiếp cận này có thể có một cuốn sách nhỏ viết về nó và yêu cầu định vị đối tượng và có thể rất phức tạp. Tôi đã viết một thư viện nhỏ cho cái này có sẵn theo yêu cầu.
Hi vọng điêu nay co ich!
Yahoo UI (YUI) cũng có chức năng trợ giúp cho việc này:
http://developer.yahoo.com/yui/examples/yahoo/yahoo_merge.html
YAHOO.namespace('example');
YAHOO.example.set1 = { foo : "foo" };
YAHOO.example.set2 = { foo : "BAR", bar : "bar" };
YAHOO.example.set3 = { foo : "FOO", baz : "BAZ" };
var Ye = YAHOO.example;
var merged = YAHOO.lang.merge(Ye.set1, Ye.set2, Ye.set3);
jquery có một boolean cho bản sao sâu. Bạn có thể làm một cái gì đó như thế:
MergeRecursive = function(arr1, arr2){
$.extend(true, arr1, arr2);
return arr1;
};
Ngoài ra, bạn có thể chỉnh sửa chức năng này để hỗ trợ n-mảng để hợp nhất.
ArrayMergeRecursive = function(){
if(arguments.length < 2){
throw new Error("ArrayMergeRecursive: Please enter two or more objects to merge!");
}
var arr1=arguments[0];
for(var i=0; i<=arguments.length; i++ ){
$.extend(true, arr1, arguments[i]);
}
return arr1;
};
Vì vậy, bây giờ bạn có thể làm
var arr1 = {'color': {'mycolor': 'red'}, 3: 5},
arr2 = {4: 10, 'color': {'favorite': 'green', 0: 'blue'}},
arr3 = ['Peter','Jhon','Demosthenes'],
results = ArrayMergeRecursive(arr1, arr2, arr3); // (arr1, arr2 ... arrN)
console.log("Result is:", results);
Tôi cần một sự hợp nhất sâu sắc đối tượng. Vì vậy, tất cả các câu trả lời khác không giúp tôi rất nhiều. _.extend và jQuery.extend làm tốt, trừ khi bạn có một mảng đệ quy như tôi làm. Nhưng nó không tệ lắm, bạn có thể lập trình nó trong năm phút:
var deep_merge = function (arr1, arr2) {
jQuery.each(arr2, function (index, element) {
if (typeof arr1[index] === "object" && typeof element === "object") {
arr1[index] = deep_merge(arr1[index], element);
} else if (typeof arr1[index] === "array" && typeof element === "array") {
arr1[index] = arr1[index].concat(element);
} else {
arr1[index] = element;
}
});
return arr1;
}
Để hợp nhất các mảng trong jQuery, còn $ .merge thì sao?
var merged = $.merge([{id:3, value:'foo3'}], [{id:1, value:'foo1'}, {id:2, value:'foo2'}]);
merged[0].id == 3;
merged[0].value == 'foo3';
merged[1].id == 1;
merged[1].value == 'foo1';
merged[2].id == 2;
merged[2].value == 'foo2';
var addProps = function (original, props) {
if(!props) {
return original;
}
if (Array.isArray(original)) {
original.map(function (e) {
return addProps(e, props)
});
return original;
}
if (!original) {
original = {};
}
for (var property in props) {
if (props.hasOwnProperty(property)) {
original[property] = props[property];
}
}
return original;
};
Xét nghiệm
console.log(addProps([{a: 2}, {z: 'ciao'}], {timestamp: 13}));
console.log(addProps({single: true}, {timestamp: 13}));
console.log(addProps({}, {timestamp: 13}));
console.log(addProps(null, {timestamp: 13}));
[ { a: 2, timestamp: 13 }, { z: 'ciao', timestamp: 13 } ]
{ single: true, timestamp: 13 }
{ timestamp: 13 }
{ timestamp: 13 }
Object.getOwnPropertyNames is not a function
sẽ làm hỏng ứng dụng.