如何获得几个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))
。 任何使用contains
或indexOf
进程最终都是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.