4
votes

Existe-t-il un moyen simple de fusionner des objets et de additionner leurs propriétés int au lieu de les remplacer dans javascript es2018?

Très bien, c'est donc ce que j'ai à l'esprit.

J'ai deux exemples d'objets

let obj3 = { x: 69 };

Je veux fusionner ces objets de manière à ce que leurs propriétés entières se combineront aussi, et ne se remplaceront pas, donc le résultat final sera

let obj1 = { x: 60 };

let obj2 = { x: 9 };

J'ai donc regardé Object.assign, mais cette fonction ne fusionne que les propriétés dans un manière qu'il favorise les propriétés sur le premier objet si les autres objets ont une propriété avec le même nom, et ne fait pas la somme des propriétés entières.

Je peux, bien sûr, simplement créer une fonction qui boucle les propriétés de chaque objet et crée un nouvel objet avec les propriétés additionnées, mais ce serait plus long et je voulais savoir s'il existe déjà une fonction qui le fait facilement comme la façon dont Object.assign agit.

Merci .


4 commentaires

Il n'y a aucune installation intégrée pour faire cela.


Ce n'est pas la définition de la fusion, ce que vous regardez est plus une somme


@CharybdeBE Je sais cela, c'est ce que j'ai finalement dit dans la question. Quelle est alors la manière la plus efficace de le faire? Ou n'y a-t-il pas d'autre moyen que de simplement boucler et boucler.


Oui, vous ne contournerez pas la boucle (et notez que Object.assign n'est pas plus efficace que la boucle, c'est juste du sucre syntaxique). Bien sûr, vous pouvez écrire des fonctions d'assistance qui répondront à vos besoins avec la même facilité d'utilisation.


3 Réponses :


4
votes

Si vous souhaitez utiliser la bibliothèque Lodash , vous pouvez le faire avec la méthode mergeWith .

<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.10/lodash.js"></script>
let obj1 = { x: 60, b: "foo", c: {y: 3, x: 'bar'} };
let obj2 = { x: 9, a: 'bar', c: {y: 4} };

const sum = _.mergeWith(obj1, obj2, (a, b) => {
  if (_.every([a, b], _.isNumber)) return a + b;
})

console.log(sum)


1 commentaires

Vous pouvez également tester d'autres types jsfiddle.net/j8sbw7zy/1 et faire autre chose



1
votes

Comme ça?

let obj1 = { x: 60 };
let obj2 = { x: 9 };

let obj3 = [obj1, obj2].reduce((s,a)=>{return {x: s.x+a.x}}, {x:0});
 
console.log(obj3);

// or more shortener:

obj3 = {x:[obj1, obj2].reduce((s,a)=> s + a.x,0)};

console.log(obj3);

// for arbitrary properties, not just x:

keys = Object.keys(obj1),
obj3 = [obj1, obj2].reduce(function (r, o) {
    keys.forEach(function (k) {
        r[k] += o[k];
    });
    return r;
}, keys.reduce(function (r, k) {
    r[k] = 0;
    return r;
}, Object.create(null)));

console.log(obj3);


4 commentaires

J'imagine que OP cherche à faire cela pour des propriétés arbitraires, pas seulement x .


Cela répond correctement à la question, mais ne va pas plus loin comme dans la réponse de Nenad Vracar. Cela ne fonctionne pas sur des objets tels que {foo: 10, bar: 'baz'} ou {foo: {bar: 10}}


Bergi, d'accord. Je répare.


Je n'ai pas fait de commentaire au début car votre code n'était que pour une valeur, et le code après la modification des propriétés arbitraires n'est pas vraiment une réponse car je cherchais un moyen simple et court. Sinon, je peux simplement faire la fonction moi-même ... mais merci pour l'effort.



2
votes

Vous pouvez réduire les objets en prenant un nombre arbitraire d'objets et réduire les paires clé / valeur en respectant les objets imbriqués.

.as-console-wrapper { max-height: 100% !important; top: 0; }
const
    add = (...a) => a                         // take all parameters
        .map(Object.entries)                  // get entries
        .reduce((a, b) => [...a, ...b], [])   // flat entries
        .reduce((o, [k, v]) => {
            o[k] = v && typeof v === 'object' // assign if object
                ? add(o[k] || {}, v)          //   result of recursive call
                : (o[k] || 0) + v;            //   or sum the value
            return o;
        }, {});

let obj1 = { x: 60, y: { z: 3 } },
    obj2 = { x: 9, y: { z: 1, a: 32 } },
    obj3 = { y: { a: 10 } },
    result = add(obj1, obj2, obj3);

console.log(result);


1 commentaires

Excellente réponse, comme toujours, mais je pense que les gens apprécieraient les commentaires et / ou les noms de variables plus explicites