2017-10-03 2 views
0

Vous cherchez un moyen de mise à jour en profondeur/fusion pour les tests:Une meilleure façon de mettre à jour en profondeur un objet en ES6 avec lodash ou toute autre bibliothèque

Actuellement, nous faisons cela:

{ 
    ..._companies, 
    ['c124']: { 
     ..._companies.c124, 
     ['fields']: { 
      ..._companies.c124.fields, 
      ['f4']: { 
       ..._companies.c124.fields.f4, 
       value: 'white' 
      } 
     } 
    } 

quand l'idéal, nous ferions:

update_merge(_companies, { 
    c124: { 
     fields: { 
      f4: { 
       value:'white' 
      } 
     } 
    } 
}) 

fusion profonde simple ne fonctionne pas dans ce cas car il remplace complètement la clé C124.

Les _companies d'origine Snippet:

const companies = { 
    c123: { 
     id: 123, 
     name: 'Company one', 
     fields: {...} // fields     
    }, 
    c124: { 
     id: 124, 
     name: 'Company two', 
     fields: { 
      f1: {...}, //...fields     
      f2: {...}, //...fields     
      f3: {...}, //...fields     
      f4: { 
       id: 4, 
       fieldType: "shortText",longText 
       title: "favorite color", 
       value: 'green', // <==== only this will change 
      }, 
     }, 
    } 
} 

Ce résultat attendu:

const companies = { 
    c123: { 
     id: 123, 
     name: 'Company one', 
     fields: {...} // fields     
    }, 
    c124: { 
     id: 124, 
     name: 'Company two', 
     fields: { 
      f1: {...}, //...fields     
      f2: {...}, //...fields     
      f3: {...}, //...fields     
      f4: { 
       id: 4, 
       fieldType: "shortText",longText 
       title: "favorite color", 
       value: 'white', // <==== this changed 
      }, 
     }, 
    } 
} 
+0

Ajoutez-vous l'objet 'company' d'origine? –

+0

... et le résultat attendu. –

+0

@OriDrori Ajouté comme demandé – Guy

Répondre

1

Lodash de _.merge() - je change la valeur du bleu au rouge):

const companies = {"c123":{"id":123,"name":"Company one","fields":{}},"c124":{"id":124,"name":"Company two","fields":{"f1":{},"f2":{},"f3":{},"f4":{"id":4,"fieldType":"shortText","title":"favorite color","value":"blue"}}}}; 
 

 
const newCompanies = _.merge({}, companies, { 
 
    c124: { 
 
     fields: { 
 
      f4: { 
 
       value:'red' 
 
      } 
 
     } 
 
    } 
 
}) 
 

 
console.log(newCompanies);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>

Une autre option consiste à utiliser _.set() de lodash si vous pouvez muter l'objet:

const companies = {"c123":{"id":123,"name":"Company one","fields":{}},"c124":{"id":124,"name":"Company two","fields":{"f1":{},"f2":{},"f3":{},"f4":{"id":4,"fieldType":"shortText","title":"favorite color","value":"blue"}}}}; 
 

 
_.set(companies, ['c124', 'fields', 'f4', 'value'], 'red') 
 

 
console.log(companies);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>

Cependant, si vous le faites souvent, et ont besoin d'un objet immuable (en Redux par exemple), Je suggère normalizing l'arbre pour avoir des feuilles moins profondes et plus accessibles.

1

Dans notre projet, nous utilisons immutability-helper. Il permet d'écrire des requêtes comme celles de MongoDB. Vaut vraiment le détour!

+0

Great! pour le bien des futurs lecteurs, si vous pouviez ajouter la solution à votre réponse: http://jsbin.com/zunehubuju/edit?js. J'accepterai volontiers votre réponse. – Guy

0

Vous pouvez essayer Ramda assocPath ou set de lodash/fp

est récursive, et vous permet de mettre à jour les clés imbriquées (note deux sont immuables

R.assocPath(['c124', 'fields', 'f4', 'value'], 'white', _companies); 
_.set(['c124', 'fields', 'f4', 'value'], 'white', _companies); 
_.set('c124.fields.f4.value', 'white', _companies);