1
votes

Fusionner deux objets JavaScript et des propriétés en conflit

Disons que j'ai deux objets:

{cars: 'ferrari', fruit: 'peach', info: 'foo', other: ['baz']}

Maintenant, je veux fusionner ces deux objets et toutes les propriétés en conflit. Résultat attendu:

{...obj1, ...obj2}

Cependant, en utilisant la répartition d'objets

{cars: ['ford', 'ferrari'], fruit: 'peach', info: 'foo', other: ['bar', 'baz']}

Renvoie

var obj1 = {cars: 'ford', fruit: 'peach', other: ['bar']}
var obj2 = {cars: 'ferrari', info: 'foo', other: ['baz']}


6 commentaires

Vous devrez parcourir manuellement les éléments de l'objet et créer le nouvel objet


@rzwnahmd pouvez-vous fournir une fonction pour faire cela?


Il y a une réponse qui montre une façon purement JavaScript de faire cela. La bibliothèque Lodash rend le code plus concis.


@VLAZ Désolé, mais je dois le faire en utilisant du javascript pur ...


la structure de données que vous décrivez est une multi-carte, au cas où vous voudriez chercher plus autour du sujet.


@Jake alors vous avez de la chance car comme je l'ai dit il y a des réponses en JavaScript pur.


4 Réponses :


0
votes

Vous pouvez fusionner par propriété et vérifier si la cible n'est pas un tableau ou si la valeur est un tableau.

const
    merge = (target, source) => Object.entries(source).reduce((o, [k, v]) => {
        if (k in o) {
            if (!Array.isArray(o[k])) o[k] = [o[k]];
            [].concat(v).forEach(item => {
                if (!o[k].includes(item)) o[k].push(item);
            });
        } else {
            o[k] = v;
        }
        return o;
    }, target);

var obj1 = { cars: 'ford', fruit: 'peach', other: ['bar'] },
    obj2 =  {cars: 'ferrari', info: 'foo', other: ['baz'] },
    result = [obj1, obj2].reduce(merge, {});

console.log(result);


0 commentaires

0
votes

Il vous suffit de le coder manuellement, il n'y a pas de moyen automatique de faire ce type de fusion. Et, en raison de la façon dont vous souhaitez fusionner les tableaux, il faut un certain nombre de conditions spéciales:

var obj1 = {cars: 'ford', fruit: 'peach', other: ['bar']}
var obj2 = {cars: 'ferrari', info: 'foo', other: ['baz']}

function merge(obj1, obj2) {
    let result = Object.assign({}, obj1);
    for (let [key, value] of Object.entries(obj2)) {
        if (result.hasOwnProperty(key)) {
            if (!Array.isArray(result[key])) {
                // target isn't an array yet, have to convert it to an array
                result[key] = [result[key]];
            }
            // now copy over either a single entry or an array of entries
            if (Array.isArray(obj2[key])) {
                // copy all the array entries over to the other array
                result[key].push(...obj2[key]);
            } else {
                // copy single entry over to the other array
                result[key].push(obj2[key]);
            }
        } else {
            // result doesn't have this property yet, just copy the value over
            result[key] = value;
        }
    }
    return result;
}

console.log(merge(obj1, obj2));


0 commentaires

0
votes

Celui-ci devrait également fonctionner:

function mergeObject(o1, o2) {
  return {
    ...o2,
    ...Object.keys(o1).reduce((r, c) => ({
      ...r, [c]: o2.hasOwnProperty(c) ? [
        ...(Array.isArray(o1[c]) ? o1[c] : [o1[c]]),
        ...(Array.isArray(o2[c]) ? o2[c] : [o2[c]]),
      ] : o1[c]
    }), {})
  }
}

var obj1 = { cars: 'ford', fruit: 'peach', other: ['bar'] }
var obj2 = { cars: 'ferrari', info: 'foo', other: ['baz'] }
const result = mergeObject(obj1, obj2)
console.log(result)


0 commentaires

0
votes

Voici ma version :)

var obj1 = {cars: 'ford', fruit: 'peach', other: ['bar']}
var obj2 = {cars: 'ferrari', info: 'foo', other: ['baz']}

var merge = (acc, [k, v]) => {
  if (k in acc) {
    acc[k] = [acc[k]].flat().concat(v)
  } else {
    acc[k] = v;
  }

  return acc;
}

var res = Object.entries(obj1).reduce(merge, obj2);


0 commentaires