31

2 つのコレクションがあるとします。

c1 -[{a:1},{a:2},{a:3}]

c2 -[{a:1},{a:7},{a:8}]

c2ユニークなアイテムを からに追加する最速の方法は何c1ですかUnderscore.JS? コレクション内の実数は2Kforc1500forc2になります。操作は頻繁に実行されるため、パフォーマンスが高くなければなりません!

更新 1 - 私はUnderscore.JS数日間しか使用していません。あるコレクションを別のコレクションに追加する方法が見つかりませんでした (c2自分でフィルター処理できます) Underscore.JS

4

4 に答える 4

53

次のようになります。

  • c1 と c2 のすべての要素を含む新しい配列を作成します。ユニオンを参照してください。
  • その組み合わせから、一意の要素のみを含む新しい配列を作成します。uniqを参照してください。

これは、すべてのオブジェクトにプロパティがある場合にのみ機能することに注意してくださいa

_.uniq(_.union(c1, c2), false, function(item, key, a){ return item.a; });

この質問で他のオプションを見つけることができます。

于 2012-11-22T14:38:01.543 に答える
16

試す:

_.uniq(_.union(c1, c2), false, _.property('a'))

詳細に:

  1. _.union(*arrays)

    渡された配列の結合を計算します。

  2. _.property(key) (バージョン 1.6.0 以降)

    渡されたオブジェクトのキー プロパティを返す関数を返します。

  3. _.uniq(array, [isSorted], [iteratee])

    ===オブジェクトの等価性をテストするために使用して、配列の重複のないバージョンを生成します。配列がソートされていることが事前にわかっている場合は、trueisSorted を渡すと、はるかに高速なアルゴリズムが実行されます。変換に基づいて一意のアイテムを計算する場合は、iteratee 関数を渡します。

于 2015-01-21T11:22:33.637 に答える
6

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()してオブジェクトのリストを作成します。

参照:uniq()

于 2012-11-26T18:17:15.430 に答える
1

両方のオブジェクトに膨大な数のプロパティがあり、このアルゴリズムが頻繁に実行されるため、ライブラリの代わりにコア 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 があります。

于 2012-11-22T13:56:56.513 に答える