2つのコレクションがある場合:
c1-[{a:1},{a:2},{a:3}]
そして
c2-[{a:1},{a:7},{a:8}]
c2
を使用してc1
からUnderscore.JS
に一意のアイテムを追加する最も速い方法は何ですか?コレクション内の実数は2K
の場合はc1
、500
の場合はc2
になります。操作は頻繁に実行されるため、パフォーマンスが必要です。
更新1-数日だけUnderscore.JS
を使用していますが、あるコレクションを別のコレクションに追加する方法が見つかりませんでした(自分でc2
をフィルタリングできます)- Underscore.JS
で些細なことですか?
試してください:
__.uniq(_.union(c1, c2), false, _.property('a'))
_
詳細に:
_.union(*arrays)
渡された配列の和集合を計算します。
_.property(key)
(バージョン1.6.0以降)
渡されたオブジェクトのキープロパティを返す関数を返します。
_.uniq(array, [isSorted], [iteratee])
_
===
_を使用してオブジェクトの等価性をテストし、重複のないバージョンの配列を生成します。配列がソートされていることが事前にわかっている場合、isSortedにtrue
を渡すと、はるかに高速なアルゴリズムが実行されます。変換に基づいて一意のアイテムを計算する場合は、反復関数を渡します。
uniq()
関数のドキュメントには、リストが並べ替えられている場合、はるかに高速に実行されることが記載されています。また、連鎖呼び出しを使用すると読みやすくなります。だからあなたができる:
__.chain(c1).union(c2).sortBy("a").uniq(true, function(item){ return item.a; }).value();
_
または、チェーンなしバージョン(11文字より短いが読みにくい)を好む場合:
__.uniq(_.sortBy(_.union(c1,c2),"a"),true, function(item){ return item.a; });
_
uniq()
のドキュメントと例では、コールバック関数がどのように機能するかを明確にしません。 uniq()
関数のアルゴリズムは、両方のリストのすべての要素でこの関数を呼び出します。この関数の結果が同じ場合、その要素は削除されます(重複していると仮定)。
union()
は実際、配列で呼び出されたときに重複を防ぎます。この事実も使用できます。
__.map(_.union(_.pluck(c1,"a"),_.pluck(c2,"a")),function (item) {return {a:item};});
_
上記のように、最初にオブジェクトのリストを単純な配列(pluck()
)に変換し、union()
を使用してそれらを結合し、最終的にmap()
を使用してオブジェクトのリストを作成します。
リファレンス: niq()
両方のオブジェクトには膨大な数のプロパティがあり、このアルゴリズムは頻繁に実行されるため、ライブラリではなくコアJavaScriptを使用することをお勧めします。
//adds all new properties from the src to dst. If the property already exists, updates the number in dst. dst and src are objects
function extendNumberSet( dst, src ) {
var allVals = [];
for ( var i = 0; i < dst.length; i++ ) {
allVals.Push(dst[i].a);
}
for ( var i = 0; i < src.length; i++ ) {
if ( allVals.indexOf( src[i].a ) === -1 ) {
dst.Push( src[i] );
}
}
}
テストするJSfiddle です。