javascript 如何在 immutable.js 中将地图列表转换为地图地图?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/29573728/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do I transform a List of Maps into a Map of Maps in immutable.js?
提问by CJ Gaconnet
Suppose I have an immutable.js List
like this:
假设我有一个List
像这样的 immutable.js :
var xs = Immutable.fromJS([{key: "k", text: "foo"}])
I want to transform that into a Map that looks like this:
我想将其转换为如下所示的 Map:
var ys = Immutable.fromJS({k: {key: "k", text: "foo"}})
How do I turn xs
into ys
idiomatically in immutable.js?
我如何在 immutable.js 中习惯地xs
变成ys
?
By idiomaticallyI mean that any intermediate structures should be immutable.js structures, and I think that any intermediate steps would use iterable compositioninstead of creating full-size intermediate representations.
通过惯用我的意思是,任何中间结构应该是immutable.js结构,我认为任何中间步骤将使用迭代组成的,而不是建立全尺寸的中间表示。
Edit: I've created a jsperf benchmarkcomparing the answers provided so far. Both non-mutating solutions feel fairly idiomatic to me; I may hold out and let votes decide the chosen answer or hold out until we can gather a collection of roughly equally idiomatic techniques.
编辑:我已经创建了一个jsperf 基准比较迄今为止提供的答案。两种非变异解决方案对我来说都非常惯用;我可能会坚持让投票决定选择的答案,或者坚持到我们可以收集到一组大致相同的惯用技术。
回答by dkl
You can reduce the input list into new Immutable.Map:
您可以将输入列表缩减为新的 Immutable.Map:
var ys = xs.reduce(
function(result, item) { return result.set(item.get('key'), item); },
Immutable.Map());
There is no intermediate representation in this case, but the immutable map has to be updated (in fact, new instance must be created) in every iteration and that that can be suboptimal (depending on the actual implementation of Immutable.Map).
在这种情况下没有中间表示,但不可变映射必须在每次迭代中更新(实际上,必须创建新实例)并且这可能是次优的(取决于 Immutable.Map 的实际实现)。
You can optimize it reducing into regular javascript object and convert it to immutable map at the end:
您可以将其优化为常规 javascript 对象并在最后将其转换为不可变映射:
var ys = Immutable.Map(xs.reduce(
function(result, item) { result[item.get('key')] = item; return result; },
{}));
But that is certainly less idiomatic.
但这肯定不那么惯用。
回答by Julien Deniau
One solution may be to use Map constructor from List:
一种解决方案可能是使用 List 中的 Map 构造函数:
const ys = Immutable.Map(xs.map(v => [v.get('key'), v]));
回答by mbeloshitsky
Seems like this, but i'm not sure about intermediate representations
看起来像这样,但我不确定中间表示
ys = Immutable
.fromJS([{key:'k', value:'xxx'}])
.toKeyedSeq()
.mapEntries(function (kv) { return [kv[1].get('key'), kv[1]]; })
PS It's strange, but i'm can only use .toKeyedSeq, not .toKeyedIterable, which is more appropriate.
PS 这很奇怪,但我只能使用 .toKeyedSeq,而不是 .toKeyedIterable,后者更合适。
回答by Allan Hortle
You can swap a List of Maps to a Map of Lists by using reduce
combined with mergeWith
.
您可以通过reduce
结合使用将地图列表交换为列表地图mergeWith
。
Reduce through the collection and merge each new item by concatenating its values together.
减少集合并通过将每个新项目的值连接在一起来合并每个新项目。
collection.reduce((rr, ii) => rr.mergeWith((aa, bb) => List().concat(aa, bb), ii))