だから、私はリストを持っています:
_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
_の最初の項目でオーバーライドしているようです。したがって、私の質問は、いくつかのリストを結合するための最も簡単な方法は何ですか(理想的には、それらのリストやその他の余分な操作を反復することなく)。
あなたはマージについて正しいです。マージは、マージリストの現在の値でインデックスを更新します。あなたの場合、あなたは持っていました
_[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にはユニオンが含まれていません。これを簡単に実装するには、各リストの各値をオブジェクトのキーとして設定し、それらのキーを結果のユニオンとして使用します。
_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);
}
_
実際、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.
List#merge
の実装はこの質問が投稿されてから変更されており、現在のバージョンでは4.0.0-rc-12
List#merge
は期待どおりに機能し、問題を解決します。