web-dev-qa-db-ja.com

いくつかのimmutable.jsリストの結合を取得する方法

だから、私はリストを持っています:

_let a = Immutable.List([1])
_

およびリストb:

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

それらからList union === List([1, 2, 3])を取得したい。

私は マージ それらの拳を試みます:

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

mergeメソッドは値ではなくインデックスで動作するため、_List a_の最初の項目を_List b_の最初の項目でオーバーライドしているようです。したがって、私の質問は、いくつかのリストを結合するための最も簡単な方法は何ですか(理想的には、それらのリストやその他の余分な操作を反復することなく)。

34
Glen Swift

あなたはマージについて正しいです。マージは、マージリストの現在の値でインデックスを更新します。あなたの場合、あなたは持っていました

_[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]); 
_

これにより、技術的にはもはや結合ではない2つの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);
}
_
26
Travis J

実際、Immutable.jsにはユニオンがあります-Setデータ構造用です:

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

Immutable.jsの素晴らしい点は、より機能的なプログラミング構造をJSに導入するのに役立つことです。この場合、共通のインターフェイスとデータ型を抽象化する機能です。リストでユニオンを呼び出すには、それらをセットに変換し、ユニオンを使用してからリストに戻します:

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.
22

List#mergeの実装はこの質問が投稿されてから変更されており、現在のバージョンでは4.0.0-rc-12List#mergeは期待どおりに機能し、問題を解決します。

1
darksmurf