Supposons que j'ai un List
immuable.js comme ceci:
var xs = Immutable.fromJS([{key: "k", text: "foo"}])
Je veux transformer cela en une carte qui ressemble à ceci:
var ys = Immutable.fromJS({k: {key: "k", text: "foo"}})
Comment transformer xs
en ys
idiomatiquement dans immutable.js?
Par idiomatiquement, je veux dire que toute structure intermédiaire devrait être une structure immuable.js, et je pense que toute étape intermédiaire utiliserait composition itérable au lieu de créer des représentations intermédiaires de taille normale.
Edit: J'ai créé un jsperf benchmark comparant les réponses fournies jusqu'à présent. Les deux solutions non mutantes me semblent assez idiomatiques; Je peux attendre et laisser les votes décider de la réponse choisie ou attendre jusqu'à ce que nous puissions rassembler un ensemble de techniques à peu près également idiomatiques.
Vous pouvez réduire la liste des entrées en un nouveau fichier Immutable.Map:
var ys = xs.reduce(
function(result, item) { return result.set(item.get('key'), item); },
Immutable.Map());
Il n'y a pas de représentation intermédiaire dans ce cas, mais la carte immuable doit être mise à jour (en fait, une nouvelle instance doit être créée) à chaque itération et cela peut être sous-optimal (selon l'implémentation réelle de Immutable.Map).
Vous pouvez l’optimiser en réduisant l’objet javascript normal et le convertir en carte immuable à la fin:
var ys = Immutable.Map(xs.reduce(
function(result, item) { result[item.get('key')] = item; return result; },
{}));
Mais c'est certainement moins idiomatique.
Une solution consiste peut-être à utiliser le constructeur Map de List:
const ys = Immutable.Map(xs.map(v => [v.get('key'), v]));
On dirait ça, mais je ne suis pas sûr des représentations intermédiaires
ys = Immutable
.fromJS([{key:'k', value:'xxx'}])
.toKeyedSeq()
.mapEntries(function (kv) { return [kv[1].get('key'), kv[1]]; })
PS C'est étrange, mais je ne peux utiliser que .toKeyedSeq, pas .toKeyedIterable, ce qui est plus approprié.
Vous pouvez échanger une liste de cartes contre une carte de listes en utilisant reduce
combiné à mergeWith
.
Réduisez la collection et fusionnez chaque nouvel élément en concaténant ses valeurs.
collection.reduce((rr, ii) => rr.mergeWith((aa, bb) => List().concat(aa, bb), ii))