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

CJ *_*net 23 javascript immutable.js

假设我有一个List像这样的immutable.js :

var xs = Immutable.fromJS([{key: "k", text: "foo"}])
Run Code Online (Sandbox Code Playgroud)

我想将其转换为如下所示的Map:

var ys = Immutable.fromJS({k: {key: "k", text: "foo"}})
Run Code Online (Sandbox Code Playgroud)

如何在immutable.js中xs转换为ys惯用语?

通过惯用我的意思是任何中间结构应该是immutable.js结构,我认为任何中间步骤都将使用可迭代组合而不是创建全尺寸中间表示.

编辑:我已经创建了一个jsperf基准,比较了目前为止提供的答案.两种非变异的解决方案对我来说都是相当惯用的; 我可以坚持让投票决定所选择的答案或坚持到我们可以收集大致同样惯用的技术集合.

dkl*_*dkl 22

您可以将输入列表缩减为新的Immutable.Map:

var ys = xs.reduce(
      function(result, item) { return result.set(item.get('key'), item); }, 
      Immutable.Map());
Run Code Online (Sandbox Code Playgroud)

在这种情况下没有中间表示,但是必须在每次迭代中更新不可变映射(事实上,必须创建新实例)并且这可能是次优的(取决于Immutable.Map的实际实现).

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

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

但这当然不那么惯用了.


Jul*_*iau 21

一种解决方案可能是使用List中的Map构造函数:

const ys = Immutable.Map(xs.map(v => [v.get('key'), v]));
Run Code Online (Sandbox Code Playgroud)


mbe*_*sky 2

看起来像这样,但我不确定中间表示

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

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