it-swarm.com.de

2 Arrays von Objekten zusammenführen

Schauen wir uns ein Beispiel an.

var arr1 = new Array({name: "lang", value: "German"}, {name: "age", value: "18"});
var arr2 = new Array({name : "childs", value: '5'}, {name: "lang", value: "German"});

Ich muss diese 2 Arrays von Objekten zusammenführen und das folgende Array erstellen.

arr3 = new Array({name: "lang", value: "German"}, {name: "age", value: "18"}, {name : "childs", value: '5'});

Gibt es eine jScript- oder jQuery-Funktion, um dies zu tun?

$ .extend passt nicht zu mir. Es kehrt zurück

arr4 = new Array({name : "childs", value: '5'}, {name: "lang", value: "German"});

Vielen Dank im Voraus, Alexander.

66
Alexander

Wenn Sie 2 Arrays von Objekten in JavaScript zusammenführen möchten. Sie können diesen einzeiligen Trick verwenden

Array.prototype.Push.apply(arr1,arr2);

Zum Beispiel

var arr1 = [{name: "lang", value: "English"},{name: "age", value: "18"}];
var arr2 = [{name : "childs", value: '5'}, {name: "lang", value: "German"}];

Array.prototype.Push.apply(arr1,arr2); 

console.log(arr1);  // final merged result will be in arr1

Ausgabe:

[{"name":"lang","value":"English"},
{"name":"age","value":"18"},
{"name":"childs","value":"5"},
{"name":"lang","value":"German"}]
60
Jahanzaib Aslam
var arr3 = [];
for(var i in arr1){
   var shared = false;
   for (var j in arr2)
       if (arr2[j].name == arr1[i].name) {
           shared = true;
           break;
       }
   if(!shared) arr3.Push(arr1[i])
}
arr3 = arr3.concat(arr2);

enter image description here

26
YOU

Für diejenigen, die mit modernen Dingen experimentieren:

var odd = [
    { name : "1", arr: "in odd" },
    { name : "3", arr: "in odd" }
];

var even = [
    { name : "1", arr: "in even" },
    { name : "2", arr: "in even" },
    { name : "4", arr: "in even" }
];

// ----
// ES5 using Array.filter and Array.find
function merge(a, b, prop){
  var reduced = a.filter(function(aitem){
      return ! b.find(function(bitem){
          return aitem[prop] === bitem[prop];
      });
  });
  return reduced.concat(b);
}
console.log( "ES5", merge(odd, even, "name") );

// ----
// ES6 arrow functions
function merge(a, b, prop){
    var reduced =  a.filter( aitem => ! b.find ( bitem => aitem[prop] === bitem[prop]) )
  return reduced.concat(b);
}
console.log( "ES6", merge(odd, even, "name") );

// ----
// ES6 one-liner
var merge = (a, b, p) => a.filter( aa => ! b.find ( bb => aa[p] === bb[p]) ).concat(b);


console.log( "ES6 one-liner", merge(odd, even, "name") );

// Results
// ( stuff in the "b" array replaces things in the "a" array )
// [
//    {
//         "name": "3",
//         "arr": "in odd"
//     },
//     {
//         "name": "1",
//         "arr": "in even"
//     },
//     {
//         "name": "2",
//         "arr": "in even"
//     },
//     {
//         "name": "4",
//         "arr": "in even"
//     }
// ]
22
bob

Ich komme immer hier von Google an und bin nicht immer zufrieden mit den Antworten. Die Antwort ist gut, aber Sie werden mit underscore.js einfacher und netter sein

DEMO: http://jsfiddle.net/guya/eAWKR/

Hier ist eine allgemeinere Funktion, die 2 Arrays mit einer Eigenschaft ihrer Objekte zusammenführt. In diesem Fall lautet die Eigenschaft 'Name'.

var arr1 = [{name: "lang", value: "English"}, {name: "age", value: "18"}];
var arr2 = [{name : "childs", value: '5'}, {name: "lang", value: "German"}];

function mergeByProperty(arr1, arr2, prop) {
    _.each(arr2, function(arr2obj) {
        var arr1obj = _.find(arr1, function(arr1obj) {
            return arr1obj[prop] === arr2obj[prop];
        });

        arr1obj ? _.extend(arr1obj, arr2obj) : arr1.Push(arr2obj);
    });
}

mergeByProperty(arr1, arr2, 'name');

console.log(arr1);

[{Name: "lang", Wert: "Deutsch"}, {Name: "Alter", Wert: "18"}, {Name: "Childs", Wert: '5'}]

18
guya

Zusammenführen von zwei Arrays:

var arr1 = new Array({name: "lang", value: "English"}, {name: "age", value: "18"});
var arr2 = new Array({name : "childs", value: '5'}, {name: "lang", value: "German"});
var result=arr1.concat(arr2);
// result: [{name: "lang", value: "English"}, {name: "age", value: "18"}, {name : "childs", value: '5'}, {name: "lang", value: "German"}]

Zusammenführen von zwei Arrays ohne doppelte Werte für 'name':

var arr1 = new Array({name: "lang", value: "English"}, {name: "age", value: "18"});
var arr2 = new Array({name : "childs", value: '5'}, {name: "lang", value: "German"});
var i,p,obj={},result=[];
for(i=0;i<arr1.length;i++)obj[arr1[i].name]=arr1[i].value;
for(i=0;i<arr2.length;i++)obj[arr2[i].name]=arr2[i].value;
for(p in obj)if(obj.hasOwnProperty(p))result.Push({name:p,value:obj[p]});
// result: [{name: "lang", value: "German"}, {name: "age", value: "18"}, {name : "childs", value: '5'}]
15
Andrew D.

Der einfachste Weg ist mit etwas ES6-Magie:

Füge zwei mit Duplikaten zusammen:

const a = [{a: 1}, {b: 2}]
const b = [{a: 1}]

const result = a.concat(b) // [{a: 1}, {b: 2}, {a: 1}]

Ohne Duplikate ist es dasselbe wie das obige Plus:

const distinct = [...new Set(result.map(item => item.YOUR_PROP_HERE))]

12
knikolov

Sehr einfach mit ES6 Spread Operator:

const array1 = [{a: 'HI!'}, {b: 'HOW'}]
const array2 = [{c: 'ARE'}, {d: 'YOU?'}]

const mergedArray = [ ...array1, ...array2 ]
console.log('Merged Array: ', mergedArray)
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>

Merged Array: [ {a: 'HI!'}, {b: 'HOW'} {c: 'ARE'}, {d: 'YOU?'} ]

6
bh4r4th

Noch eine andere Version, die reduce() method verwendet:

var arr1 = new Array({name: "lang", value: "English"}, {name: "age", value: "18"});
var arr2 = new Array({name : "childs", value: '5'}, {name: "lang", value: "German"});

var arr = arr1.concat(arr2).reduce(function(prev, current, index, array){ 
   
   if(!(current.name in prev.keys)) {
      prev.keys[current.name] = index;
      prev.result.Push(current);   
   } 
   else{
       prev.result[prev.keys[current.name]] = current;
   }  

   return prev;
},{result: [], keys: {}}).result;
  
document.getElementById("output").innerHTML = JSON.stringify(arr,null,2);    
<pre id="output"/>

6

Mit lodash:

_.uniqBy([...arr1, ...arr2], 'name')
5
Pietro

So habe ich ein ähnliches Problem in einem ES6-Kontext behandelt:

function merge(array1, array2, prop) {
    return array2.map(function (item2) {
        var item1 = array1.find(function (item1) {
            return item1[prop] === item2[prop];
        });
        return Object.assign({}, item1, item2);
    });
}

Anmerkung: Dieser Ansatz gibt keine Elemente aus Array1 zurück, die nicht in Array2 angezeigt werden.


EDIT: Ich habe einige Szenarien, in denen ich Elemente beibehalten möchte, die nicht im zweiten Array erscheinen, also habe ich eine andere Methode gefunden.

function mergeArrays(arrays, prop) {
    const merged = {};

    arrays.forEach(arr => {
        arr.forEach(item => {
            merged[item[prop]] = Object.assign({}, merged[item[prop]], item);
        });
    });

    return Object.values(merged);
}

var arr1 = [
    { name: 'Bob', age: 11 },
    { name: 'Ben', age: 12 },
    { name: 'Bill', age: 13 },
];

var arr2 = [
    { name: 'Bob', age: 22 },
    { name: 'Fred', age: 24 },
    { name: 'Jack', age: 25 },
    { name: 'Ben' },
];

console.log(mergeArrays([arr1, arr2], 'name'));
5
marktuk

Sie können ein Objekt verwenden, um Ihre Eigenschaften zu sammeln, während Sie Duplikate ersetzen, und dieses Objekt dann zu einem Array erweitern/reduzieren. Etwas wie das:

function merge(args) {
    args  = Array.prototype.slice.call(arguments);
    var o = { };
    for(var i = 0; i < args.length; ++i)
        for(var j = 0; j < args[i].length; ++j)
            o[args[i][j].name] = args[i][j].value;
    return o;
}

function expand(o) {
    var a = [ ];
    for(var p in o)
        if(o.hasOwnProperty(p))
            a.Push({ name: p, value: o[p]});
    return a;
}

var arr1 = new Array({name: "lang", value: "English"}, {name: "age", value: "18"});
var arr2 = new Array({name : "childs", value: '5'}, {name: "lang", value: "German"});
var arr3 = expand(merge(arr1, arr2));

Ich weiß nicht, ob dies der schnellste Weg ist, aber es funktioniert für eine beliebige Anzahl von Eingabearrays. zum Beispiel das:

var a = expand(
    merge(
        [{name: "lang", value: "English"}, {name: "age", value: "18"}],
        [{name: "childs", value: '5'}, {name: "lang", value: "German"}],
        [{name: 'lang', value: 'Pancakes'}]
    )
);

Gibt Ihnen in a dasselbe wie in arr3, wobei "deutsch" durch "Pancakes" ersetzt wurde.

Bei diesem Ansatz wird davon ausgegangen, dass Ihre Objekte natürlich alle dieselbe {name: ..., value: ...}-Form haben.

Sie können es hier sehen (öffnen Sie Ihre Konsole bitte): http://jsfiddle.net/ambiguous/UtBbB/

4
mu is too short

Mit ES6 geht das ganz einfach wie folgt:

var arr1 = new Array({name: "lang", value: "German"}, {name: "age", value: "18"});
var arr2 = new Array({name : "childs", value: '5'}, {name: "lang", value: "German"});
var arr3 = [...arr1, ...arr2];

Ausgabe:

    arr3 = [
      {"name":"lang","value":"German"},
      {"name":"age","value":"18"},
      {"name":"childs","value":"5"},
      {"name":"lang","value":"German"}
    ]
4

Ich stand vor demselben Problem und basierend auf guya answer habe ich die Unterstreichungsbibliothek erweitert und auch etwas mehr Funktionalität hinzugefügt, die ich brauchte. Hier ist der Gist .

/**
 * Merges two object-like arrays based on a key property and also merges its array-like attributes specified in objectPropertiesToMerge.
 * It also removes falsy values after merging object properties.
 *
 * @param firstArray The original object-like array.
 * @param secondArray An object-like array to add to the firstArray.
 * @param keyProperty The object property that will be used to check if objects from different arrays are the same or not.
 * @param objectPropertiesToMerge The list of object properties that you want to merge. It all must be arrays.
 * @returns The updated original array.
 */
function merge(firstArray, secondArray, keyProperty, objectPropertiesToMerge) {

    function mergeObjectProperties(object, otherObject, objectPropertiesToMerge) {
        _.each(objectPropertiesToMerge, function (eachProperty) {
            object[eachProperty] = _.chain(object[eachProperty]).union(otherObject[eachProperty]).compact().value();
        });
    }

    if (firstArray.length === 0) {
        _.each(secondArray, function (each) {
            firstArray.Push(each);
        });
    } else {
        _.each(secondArray, function (itemFromSecond) {
            var itemFromFirst = _.find(firstArray, function (item) {
                return item[keyProperty] === itemFromSecond[keyProperty];
            });

            if (itemFromFirst) {
                mergeObjectProperties(itemFromFirst, itemFromSecond, objectPropertiesToMerge);
            } else {
                firstArray.Push(itemFromSecond);
            }
    });
    }

    return firstArray;
}

_.mixin({
            merge: merge
        });

Hoffe, dass es nützlich ist! Grüße!

2
Nahuel Barrios

Einfache Lösung

var tx = [{"id":1},{"id":2}];
var tx1 = [{"id":3},{"id":4}];


var txHistory = tx.concat(tx1)

console.log(txHistory); 
// output
 // [{"id":1},{"id":2},{"id":3},{"id":4}];
2
ngCourse

Ich war vor kurzem mit diesem Problem überrascht und kam mit der Hoffnung hierher, eine Antwort zu haben, aber die akzeptierte Antwort verwendet 2 für In-Loops, die ich nicht bevorzugen würde. Ich habe es endlich geschafft, mich selbst zu machen. Kommt nicht auf irgendeine Bibliothek an:

function find(objArr, keyToFind){
    var foundPos = objArr.map(function(ob){
        return ob.type;
    }).indexOf(keyToFind);
    return foundPos;
}

function update(arr1,arr2){
    for(var i = 0, len = arr2.length, current; i< len; i++){
        var pos = find(arr1, arr2[i].name); 
        current = arr2[i];
        if(pos !== -1) for(var key in arr2) arr1[pos][key] = arr2[key];
        else arr1[arr1.length] = current;
    } 
}

Dies hält auch die Reihenfolge von arr1 aufrecht.

2

Was ist mit jQuery Merge?

http://api.jquery.com/jQuery.merge/

jsFiddle-Beispiel hier: http://jsfiddle.net/ygByD/

2
321X

sie könnten folgende Funktion verwenden

const merge = (a, b, key = "id") =>
  a.filter(elem => !b.find(subElem => subElem[key] === elem[key]))
   .concat(b);

und versuche

merge(arr1, arr2, 'name');
1
Diogo Alves

Hier filtere ich zuerst arr1 basierend auf dem in arr2 vorhandenen Element oder nicht. Wenn es vorhanden ist, füge es nicht zum resultierenden Array hinzu, sonst füge es hinzu. Und dann füge ich arr2 an das Ergebnis an.

arr1.filter(item => {
  if (!arr2.some(item1=>item.name==item1.name)) {
    return item
  }
}).concat(arr2)
1
maulik bhatt

Mit lodash wollen Sie _.uniqBy

var arr3 = _.uniqBy(arr1.concat(arr2), 'name'); // es5

let arr3 = _.uniqBy([...arr1, ...arr2], 'name'); // es6

Reihenfolge von arr1, arr2 zählt!

Siehe docs https://lodash.com/docs/4.17.4#uniqBy

0
danday74

Hier ist ein jQuery-Plugin, das ich geschrieben habe, um zwei Objekt-Arrays mit einem Schlüssel zusammenzuführen. Beachten Sie, dass dadurch das Zielarray an Ort und Stelle geändert wird.

(function($) {
  $.extendObjectArray = function(destArray, srcArray, key) {
    for (var index = 0; index < srcArray.length; index++) {
      var srcObject = srcArray[index];
      var existObject = destArray.filter(function(destObj) {
        return destObj[key] === srcObject[key];
      });
      if (existObject.length > 0) {
        var existingIndex = destArray.indexOf(existObject[0]);
        $.extend(true, destArray[existingIndex], srcObject);
      } else {
        destArray.Push(srcObject);
      }
    }
    return destArray;
  };
})(jQuery);

var arr1 = [
  { name: "lang",   value: "English" },
  { name: "age",    value: "18"      }
];
var arr2 = [
  { name: "childs", value: '5'       },
  { name: "lang",   value: "German"  }
];
var arr3 = $.extendObjectArray(arr1, arr2, 'name');

console.log(JSON.stringify(arr3, null, 2));
.as-console-wrapper { top: 0; max-height: 100% !important; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>


ES6-Version

(function($) {
  $.extendObjectArray = (destArr, srcArr, key) => {
    srcArr.forEach(srcObj => (existObj => {
      if (existObj.length) {
        $.extend(true, destArr[destArr.indexOf(existObj[0])], srcObj);
      } else {
        destArr.Push(srcObj);
      }
    })(destArr.filter(v => v[key] === srcObj[key])));
    return destArr;
  };
})(jQuery);
0
Mr. Polywhirl

Aus meinem Kopf heraus - try jquery extend

var arr3 = jQuery.extend(arr1,arr2....)
0
Xhalent

Basierend auf @ YOUs Antwort, aber die Reihenfolge beibehalten:

var arr3 = [];
for(var i in arr1){
   var shared = false;
   for (var j in arr2)
       if (arr2[j].name == arr1[i].name) {
           arr3.Push(arr1[j]
           shared = true;
           break;
       }
   if(!shared) arr3.Push(arr1[i])
}

for(var j in arr2){
   var shared = false;
   for (var i in arr1)
       if (arr2[j].name == arr1[i].name) {
           shared = true;
           break;
       }
   if(!shared) arr3.Push(arr2[j])
}
arr3

Ich weiß, dass diese Lösung weniger effizient ist, aber sie ist notwendig, wenn Sie die Reihenfolge beibehalten und die Objekte trotzdem aktualisieren möchten.

0
hcarreras

Wenn Sie die beiden Arrays zusammenführen möchten, aber doppelte Objekte entfernen möchten, verwenden Sie Folgendes .. _. Duplikate werden auf .uniqueId jedes Objekts angegeben

function mergeObjectArraysRemovingDuplicates(firstObjectArray, secondObjectArray) {
  return firstObjectArray.concat(
    secondObjectArray.filter((object) => !firstObjectArray.map((x) => x.uniqueId).includes(object.uniqueId)),
  );
}
0
daveanderson88
merge(a, b, key) {
    let merged = [];
    a.forEach(aitem => {
        let found = b.find( bitem => aitem[key] === bitem[key]);
        merged.Push(found? found: aitem);
    });
    return merged;
}
0
Kyaw

var newArray = yourArray.concat(otherArray); console.log('Concatenated newArray: ', newArray);

0
javaScriptBeard
const extend = function*(ls,xs){
   yield* ls;
   yield* xs;
}

console.log( [...extend([1,2,3],[4,5,6])]  );
0
codemonkey