2016-07-01 1 views
2

J'essaie de trouver une fonction équivalente à Lodash's merge en utilisant Ramda qui effectue une "fusion" ou une "extension" basée sur une clé d'objet récursive. Le comportement est similaire à ce qui suit:Recursive "fusionner" ou "étendre" avec Ramda?

let merged = R.someMethod(
    { name: 'Matt', address: { street: 'Hawthorne', number: 22, suffix: 'Ave' }}, 
    { address: { street: 'Pine', number: 33 }} 
); 

console.log(merged); 

// => { name: 'Matt', address: { street: 'Pine', number: 33, suffix: 'Ave' }} 

Je remarqué dans le pull request suivant celui R.set a été brièvement présenté, mais rolled back peu après. Cette fonctionnalité a-t-elle été capturée par la bibliothèque Ramda depuis?

Cette fonctionnalité est-elle disponible dans Ramda?

Répondre

2

Ramda n'inclut pas une telle fonction pour le moment.

Il y a eu plusieurs tentatives pour en créer un, mais elles semblent se fonder sur la notion de ce qui est vraiment requis pour une telle fonction.

N'hésitez pas à raise an issue si vous pensez que cela vaut la peine d'ajouter.

+0

je pense qu'il est utile de créer un problème, mais je ne voudrais pas ressasser les mêmes vieux morceaux sur la façon de traiter avec des valeurs non définies, les tableaux, la fusion etc. Je n'apporte pas vraiment d'opinions nuancées sur la table , et je ne suis pas sûr que le désir d'avoir la fonctionnalité elle-même parle très fort à ce stade ... – Himmel

+0

Comme vous le souhaitez, bien sûr. Je pense qu'il y a une pression continue mais assez faible pour ajouter une telle fonction. Mais beaucoup, y compris moi, ont résisté, car aucune API ne semble fantastique, surtout face aux chaînes de prototypes, aux structures «indéfinies» et cycliques. Mais c'est probablement un cas d'être parfait l'ennemi du bien. –

6

Une fonction récursive relativement simple peut être créée en utilisant R.mergeWith.

function deepMerge(a, b) { 
    return (R.is(Object, a) && R.is(Object, b)) ? R.mergeWith(deepMerge, a, b) : b; 
} 

deepMerge({ name: 'Matt', address: { street: 'Hawthorne', number: 22, suffix: 'Ave' }}, 
      { address: { street: 'Pine', number: 33 }}); 

//=> {"address": {"number": 33, "street": "Pine", "suffix": "Ave"}, "name": "Matt"} 
+0

Je suppose que cela dépend de la façon dont vous voulez qu'une telle fonction fonctionne, mais je préfère que toute clé/valeur passée comme second argument écrase une clé/valeur correspondante passée en premier argument, malgré le type de la valeur. Une telle fonctionnalité est capturée par '(R.is (Object, b))? ... 'plutôt que' (R.is (Object, a))? ... '. – Himmel

+1

Si vous manipulez potentiellement différents types à la même clé, vérifiez que 'a' et' b' sont des objets avant d'appeler 'mergeWith'. J'ai mis à jour l'exemple pour refléter cela. –

+0

Version légèrement modifiée pour fonctionner avec des tableaux simples '' 'const deepMerge = (a, b) => R.isArrayLike (b) &&! R.is (Objet, b [0]) ? b : (R.is (Object, a) && R.is (Object, b))? R.mergeWith (deepMerge, a, b): b''' – baio