如何获得几个immutable.js列表的联合

所以,我列出了一个:

let a = Immutable.List([1]) 

和列表b:

 let b = Immutable.List([2, 3]) 

我想从他们得到列表union === List([1, 2, 3])

我试图合并他们的拳头:

 let union = a.merge(b); // List([2, 3]) 

看起来像merge方法操作与索引,而不是值,所以重写List a的第一个项目与List b第一个项目。 所以,我的问题是什么是最简单的方式来获得几个列表的联合(理想情况下,没有迭代他们和其他额外的操作)。

你对合并是正确的。 合并将使用合并列表的当前值更新索引。 所以在你的情况下,你有

 [0] = 1 

并与之合并

 [0] = 2 [1] = 3 

最后用[0]=2覆盖[0]=1 ,然后设置[1]=3 ,合并后得到观察的[2,3]数组。

解决这个问题的一个非常简单的方法就是使用concat

 var a = Immutable.List([1]); var b = Immutable.List([2,3]); var c = a.concat(b); 

这将适用于这种情况。 但是,如果情况更复杂,这可能是不正确的。 例如,

 var a = Immutable.List([1,4]); var b = Immutable.List([2,3,4]); 

这会给你两个4,这在技术上不是一个工会了。 不幸的是,在Immutable中没有包含联盟。 实现它的简单方法是将每个列表中的每个值设置为对象的关键字,然后将这些关键字作为生成的联合。

jsFiddle Demo

 function union(left,right){ //object to use for holding keys var union = {}; //takes the first array and adds its values as keys to the union object left.forEach(function(x){ union[x] = undefined; }); //takes the second array and adds its values as keys to the union object right.forEach(function(x){ union[x] = undefined; }); //uses the keys of the union object in the constructor of List //to return the same type we started with //parseInt is used in map to ensure the value type is retained //it would be string otherwise return Immutable.List(Object.keys(union).map(function(i){ return parseInt(i,10); })); } 

这个过程是O(2(n+m)) 。 任何使用containsindexOf进程最终都是O(n^2) ,这就是为什么这里使用了密钥。

后期编辑

超高性能

 function union(left,right){ var list = [], screen = {}; for(var i = 0; i < left.length; i++){ if(!screen[left[i]])list.push(i); screen[left[i]] = 1; } for(var i = 0; i < right.length; i++){ if(!screen[right[i]])list.push(i); screen[right[i]] = 1; } return Immutable.List(list); } 

实际上Immutable.js确实有一个联合 – 它是Set数据结构:

https://facebook.github.io/immutable-js/docs/#/Set/union

Immutable.js最棒的地方在于它可以将更多的函数式编程结构引入到JS中 – 在这个例子中是一个通用的接口和抽象数据types的能力。 所以为了在你的列表上调用union – 将它们转换为集合,使用union并将它们转换回列表:

 var a = Immutable.List([1, 4]); var b = Immutable.List([2, 3, 4]); a.toSet().union(b.toSet()).toList(); //if you call toArray() or toJS() on this it will return [1, 4, 2, 3] which would be union and avoid the problem mentioned in Travis J's answer.