简体   繁体   English

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

[英]How to get union of several immutable.js Lists

So, I have List a: 所以,我有List a:

let a = Immutable.List([1])

and List b: 和清单b:

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

I want to get List union === List([1, 2, 3]) from them. 我想从它们获得List union === List([1, 2, 3])

I try to merge them fist: 我试着它们合并在一起:

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

It seems like merge method operates with indexes, not with values so overrides first item of List a with first item of List b . 似乎merge方法使用索引操作,而不是使用值,因此使用List b第一项覆盖List a的第一项。 So, my question is what is the most simple way to get union of several lists (ideally without iterating over them and other extra operations). 所以,我的问题是什么是获得多个列表联合的最简单方法(理想情况下不会迭代它们和其他额外的操作)。

You are correct about merge. 你对合并是正确的。 Merge will update the index with the current value of the merging list. 合并将使用合并列表的当前值更新索引。 So in your case you had 所以在你的情况下,你有

[0] = 1

and merged it with 并将其合并

[0] = 2
[1] = 3

which ended up overwriting [0]=1 with [0]=2 , and then set [1]=3 resulting in your observed [2,3] array after merging. 最终用[0]=2覆盖[0]=1 ,然后设置[1]=3导致合并后观察到的[2,3]数组。

A very simple approach to solving this would be to use concat 解决这个问题的一个非常简单的方法是使用concat

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

var c = a.concat(b);

And it will work for this situation. 它将适用于这种情况。 However, if the situation is more complex, this may be incorrect. 但是,如果情况更复杂,这可能是不正确的。 For example, 例如,

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

this would give you two 4's which is not technically a union anymore. 这将给你两个4,这在技术上不再是一个联盟。 Unfortunately there is no union included in Immutable. 不幸的是,Immutable中没有联盟。 An easy way to implemented it would be to set each value in each list as the key to an object, and then take those keys as the resulting union. 实现它的一种简单方法是将每个列表中的每个值设置为对象的键,然后将这些键作为结果联合。

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); 
 }));
}

This process is O(2(n+m)) . 该过程为O(2(n+m)) Any process which uses contains or indexOf is going to end up being O(n^2) so that is why the keys were used here. 任何使用containsindexOf进程最终都会成为O(n^2) ,这就是为什么在这里使用密钥的原因。

late edit 晚编辑

Hyper-performant 超高性能

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);
}

Actually Immutable.js does have a union - it is for the Set data structure: 实际上Immutable.js确实有一个联合 - 它用于Set数据结构:

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

The great thing about Immutable.js is it helps introduce more functional programming constructs into JS - in this instance a common interface and the ability to abstract away data types. 关于Immutable.js的好处是它有助于将更多函数式编程结构引入JS - 在这个例子中是一个通用接口和抽象数据类型的能力。 So in order to call union on your lists - convert them to sets, use union and then convert them back to lists: 因此,为了在列表上调用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.

自发布此问题以来, List#merge的实现已更改,并且在当前版本4.0.0-rc-12 List#merge按预期工作并解决了问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM