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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/30126698/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 04:42:51  来源:igfitidea点击:

How to get union of several immutable.js Lists

javascriptnode.jslistimmutabilityimmutable.js

提问by Glen Swift

So, I have 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.

我想union === List([1, 2, 3])从他们那里得到 List 。

I try to mergethem fist:

我尝试它们合并

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

It seems like mergemethod operates with indexes, not with values so overrides first item of List awith first item of List b. 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).

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

采纳答案by Travis J

You are correct about merge. Merge will update the index with the current value of the merging list. So in your case you had

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

[0] = 1

and merged it with

并将其与

[0] = 2
[1] = 3

which ended up overwriting [0]=1with [0]=2, and then set [1]=3resulting in your observed [2,3]array after merging.

这结束了覆盖[0]=1[0]=2,然后设置[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. Unfortunately there is no union included in 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.

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

jsFiddle Demo

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)). Any process which uses containsor indexOfis going to end up being O(n^2)so that is why the keys were used here.

这个过程是O(2(n+m))。任何使用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);
}

回答by Geoffrey Abdallah

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. So in order to call union on your lists - convert them to sets, use union and then convert them back to lists:

Immutable.js 的伟大之处在于它有助于将更多的函数式编程结构引入 JS - 在这个例子中是一个通用接口和抽象数据类型的能力。因此,为了在您的列表上调用 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.

回答by darksmurf

The implementation of List#mergehas changed since this question was posted, and in the current version 4.0.0-rc-12List#mergeworks as expected and solves the issue.

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