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

所以,我有列表a:

let a = Immutable.List([1])

和列表b:

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

我想从它们中获取List union === List([1,2,3])。

我试着merge他们拳头:

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

似乎合并方法与索引一起操作,而不是使用值,所以覆盖列表a的第一项与列表b的第一项。所以,我的问题是什么是最简单的方法来获得几个列表的联合(理想情况下不迭代他们和其他额外的操作)。

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

[0] = 1

并将其合并

[0] = 2
[1] = 3

最终覆盖[0] = 1,其中[0] = 2,然后设置[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);
}
翻译自:https://stackoverflow.com/questions/30126698/how-to-get-union-of-several-immutable-js-lists

转载注明原文:javascript – 如何获得几个immutable.js列表的联合