İki ilişkilendirilebilir diziyi JavaScript'te birleştirmenin en iyi / standart yolu nedir? Herkes sadece kendi for
döngüsünü kırarak mı yapıyor?
İki ilişkilendirilebilir diziyi JavaScript'te birleştirmenin en iyi / standart yolu nedir? Herkes sadece kendi for
döngüsünü kırarak mı yapıyor?
Yanıtlar:
jquery ile arayabilirsiniz $.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
(dernek dizileri js cinsinden nesnelerdir)
buraya bakın: http://api.jquery.com/jQuery.extend/
edit: önerilen rymo gibi, bu şekilde yapmak daha iyidir:
obj3 = $.extend({}, obj1, obj2);
obj3 == {a: 4, b: 2, c: 110}
Burada olduğu gibi obj1 (ve obj2) değişmeden kalır.
edit2: 2018'de bunu yapmanın yolu şöyledir Object.assign
:
var obj3 = Object.assign({}, obj1, obj2);
obj3 === {a: 4, b: 2, c: 110} // Pseudo JS
ES6 ile çalışıyorsanız bu Spread Operator ile elde edilebilir :
const obj3 = { ...obj1, ...obj2 };
obj1
, hedef olarak boş bir nesne kullanın:$.extend({}, obj1, obj2)
Object.assign()
zaten kitaplığı kullanmıyorsanız JQuery'ye dayanmayan , @manfred kullanarak çözümü kontrol edin .
Şimdi 2016'da en iyi / standart yolun Object.assign ()
Pure Javascript olduğunu söyleyebilirim . JQuery gerekmez.
obj1 = {a: 1, b: 2};
obj2 = {a: 4, c: 110};
obj3 = Object.assign({},obj1, obj2); // Object {a: 4, b: 2, c: 110}
Daha fazla bilgi, örnekler ve çoklu doldurma:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign
Prototip bunu şu şekilde yapar:
Object.extend = function(destination, source) {
for (var property in source) {
if (source.hasOwnProperty(property)) {
destination[property] = source[property];
}
}
return destination;
};
olarak adlandırılır, örneğin:
var arr1 = { robert: "bobby", john: "jack" };
var arr2 = { elizabeth: "liz", jennifer: "jen" };
var shortnames = Object.extend(arr1,arr2);
EDIT : yorumlarda bucabay tarafından doğru şekilde işaretlenmiş hasOwnProperty () denetimi eklendi
Basit tutun ...
function mergeArray(array1,array2) {
for(item in array1) {
array2[item] = array1[item];
}
return array2;
}
arrau1.prototype
hasOwnProperty
kontrole ihtiyacınız var . Nesnelere diziler olarak atıfta bulunulması da yanıltıcıdır (nesnelerdir), arg adları dizi2'nin mutasyona uğradığını veya yeni bir nesnenin döndürülmesi gerektiğini belirtmelidir. Cevabı düzenlerdim ama aslında Jonathan Fingland'ın düzeltilmiş olan düzeltilmiş yanıtı neredeyse tam olarak olurdu .
Alt çizgi ayrıca bir genişletme yöntemine sahiptir:
Kaynak nesnelerdeki tüm özellikleri hedef nesneye kopyalayın. Sırayla, bu nedenle son kaynak önceki bağımsız değişkenlerde aynı adın özelliklerini geçersiz kılar.
_.extend(destination, *sources)
_.extend({name : 'moe'}, {age : 50});
=> {name : 'moe', age : 50}
In Dojo'da , 2-nesneler / diziler "birleştirme" olacağını lang.mixin(destination, source)
- Ayrıca, bir hedefe doğru vb birden çok kaynak karıştırabilirsiniz - bkz mixin işlevin referansı detayları için.
adlar aynı, ancak değerler aynı değilse bir özelliğin üzerine yazmak istiyor musunuz?
Orijinal nesnelerden birini kalıcı olarak değiştirmek ister misiniz?
veya yeni bir birleştirilmiş nesnenin döndürülmesini mi istiyorsunuz?
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???' });
...
Bu sadece bir uzanır uyarısı yinelemeli, nesnelerin. Ayrıca, bu özyinelemeli fonksiyonun TCO ( Kuyruk Çağrısı Optimize Edildi ) olduğuna dikkat edin, çünkü dönüşü kendisine yapılan son çağrıdır.
Ayrıca, hedeflenen özellikler isteyebilirsiniz . Bu durumda, nesnelere dayalı nesneleri yoğunlaştırmak isteyebilirsiniz id
,quantity
ya da başka bir özellik. Bu yaklaşım hakkında yazılmış küçük bir kitap olabilir ve nesne yan yana yerleştirilmesini gerektirir ve çok karmaşık olabilir. Bunun için talep üzerine küçük bir kütüphane yazdım.
Bu yardımcı olur umarım!
Yahoo UI (YUI) ayrıca bunun için bir yardımcı işleve sahiptir:
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 derin kopya için bir boole sahiptir. Böyle bir şey yapabilirsiniz:
MergeRecursive = function(arr1, arr2){
$.extend(true, arr1, arr2);
return arr1;
};
Ayrıca birleştirmek üzere n-dizilerini desteklemek için bu işlevi düzenleyebilirsiniz.
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;
};
Şimdi yapabilirsin
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);
Derin nesne birleştirme ihtiyacım vardı. Yani diğer tüm cevaplar bana pek yardımcı olmadı. _.extend ve jQuery.extend, benim gibi yinelemeli bir diziniz olmadığı sürece iyi yapar. Ama o kadar da kötü değil, beş dakika içinde programlayabilirsiniz:
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;
}
JQuery'de dizileri birleştirmek için $ .merge?
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;
};
Testler
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
uygulamayı kilitleyeceğim.