203 votes

Fusionner 2 tableaux d'objets

Prenons un exemple.

var arr1 = new Array({name: "lang", value: "English"},
                     {name: "age", value: "18"});

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

Je dois fusionner ces deux tableaux d'objets et créer le tableau suivant :

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

Existe-t-il une fonction JavaScript ou jQuery pour faire cela ?

$.extend ne me convient pas. Il retourne

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

4voto

mu is too short Points 205090

Vous pourriez utiliser un objet pour collecter vos propriétés tout en remplaçant les doublons, puis étendre ou aplatir cet objet en un tableau. Quelque chose comme ça :

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

Je ne sais pas si c'est la méthode la plus rapide mais elle fonctionne pour n'importe quel nombre de tableaux d'entrée ; par exemple, ceci :

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

Vous obtenez la même chose en a qui était dans arr3 avec "Allemand" remplacé par "Pancakes".

Cette approche suppose que vos objets ont tous la même valeur. {name: ..., value: ...} forme bien sûr.

Vous pouvez le voir fonctionner ici (ouvrez votre console s'il vous plaît) : http://jsfiddle.net/ambiguous/UtBbB/

3voto

Diogo Alves Points 21

Vous pouvez utiliser la fonction suivante

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

et essayer

merge(arr1, arr2, 'name');

2voto

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

function mergeArrayByProperty(arr1, arr2, prop) {
    var newArray =
        arr1.map(item => {
            if (typeof (item[prop]) !== "undefined") {
                var nItems = arr2.filter(ni => { if (typeof (ni[prop]) !== "undefined" && ni[prop] === item[prop]) return ni; });
                if (nItems.length > 0) {
                    item = Object.assign({}, item, nItems[0]);
                }
                return item;
            }
        });
    var arr2nd = arr2.flatMap(item => { return item[prop] });
    var arr1nd = arr1.flatMap(item => { return item[prop] });
    var nonDupArr = arr2nd.map(p => { if (arr1nd.includes(p) === false) return arr2.filter(i2 => { if (i2[prop] === p) return Object.assign({}, i2) })[0]; });
    return newArray.concat(nonDupArr).filter(i=>{if(i !== null)return i})
}
var arr = mergeArrayByProperty(arr1, arr2, 'name');
console.log(arr)

Je sais qu'on a déjà répondu à cette question à plusieurs reprises, mais je voulais la partager.

Cette opération trouve la clé en double dans le premier tableau et fusionne les objets du second tableau ayant la même valeur de clé. Si aucune valeur n'est trouvée dans le second tableau, elle utilise l'objet original. Comme vous pouvez le voir, la langue n'est trouvée qu'une seule fois dans l'ensemble des résultats, l'allemand étant la valeur.

2voto

321X Points 1216

Qu'en est-il de jQuery Merge ?

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

Exemple de jsFiddle ici : http://jsfiddle.net/ygByD/

2voto

Nahuel Barrios Points 817

J'étais confronté au même problème et en me basant sur réponse de guya J'ai étendu la bibliothèque underscore et ajouté un peu plus de fonctionnalités dont j'avais besoin. Voici le 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
        });

J'espère qu'il sera utile ! Salutations !

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X