Javascript 如何将immutable.js中的地图列表转换为地图地图?

Javascript 如何将immutable.js中的地图列表转换为地图地图?,javascript,immutable.js,Javascript,Immutable.js,假设我有一个不可变的.js列表,如下所示: var xs = Immutable.fromJS([{key: "k", text: "foo"}]) var ys = Immutable.fromJS({k: {key: "k", text: "foo"}}) 我想将其转换为如下所示的地图: var xs = Immutable.fromJS([{key: "k", text: "foo"}]) var ys = Immutable.fromJS({k: {key: "k", text:

假设我有一个不可变的.js
列表,如下所示:

var xs = Immutable.fromJS([{key: "k", text: "foo"}])
var ys = Immutable.fromJS({k: {key: "k", text: "foo"}})
我想将其转换为如下所示的地图:

var xs = Immutable.fromJS([{key: "k", text: "foo"}])
var ys = Immutable.fromJS({k: {key: "k", text: "foo"}})
在immutable.js中,如何按照惯用方式将
xs
转换为
ys

我的习惯用法是指任何中间结构都应该是immutable.js结构,我认为任何中间步骤都将使用,而不是创建完整的中间表示


编辑:我已经创建了一个比较到目前为止提供的答案的方法。这两种非变异的解决方案对我来说都相当习惯;我可能会坚持让投票来决定选择的答案,或者坚持到我们能够收集到大致相同的惯用技巧。

似乎是这样的,但我不确定中间表示法

ys = Immutable
    .fromJS([{key:'k', value:'xxx'}])
    .toKeyedSeq()
    .mapEntries(function (kv) { return [kv[1].get('key'), kv[1]]; })

PS这很奇怪,但我只能使用.toKeyedSeq,而不能使用.toKeyedIterable,这更合适。

您可以将输入列表缩减为新的不可变。映射:

var ys = xs.reduce(
      function(result, item) { return result.set(item.get('key'), item); }, 
      Immutable.Map());
在这种情况下没有中间表示,但不可变映射必须在每次迭代中更新(事实上,必须创建新实例),这可能是次优的(取决于不可变.map的实际实现)

您可以将其优化为常规javascript对象,并最终将其转换为不可变映射:

var ys = Immutable.Map(xs.reduce(
      function(result, item) { result[item.get('key')] = item; return result; }, 
      {}));

但这肯定不那么惯用。

一种解决方案可能是使用列表中的映射构造函数:

const ys = Immutable.Map(xs.map(v => [v.get('key'), v]));

您可以使用
reduce
mergeWith
组合使用,将地图列表交换为列表地图

通过集合进行缩减,并通过将每个新项的值连接在一起来合并它们

collection.reduce((rr, ii) => rr.mergeWith((aa, bb) => List().concat(aa, bb), ii))

你真的想要地图地图,还是想要对象地图?@Bergi Map of Maps–一路不变。谢谢你的合理回答!我认为这是最好的答案。但是,当我比较每次迭代时更新映射的性能与最后构建一个新映射的性能时,我始终发现第一种方法几乎快10%,这与您在最后提到的相反: