你对合并是正确的。合并将使用合并列表的当前值更新索引。所以在你的情况下,你有
[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);
}