Underscore: _.unionはオブジェクトの配列では機能しません

作成日 2015年10月02日  ·  32コメント  ·  ソース: jashkenas/underscore

_.unionは、オブジェクトの配列が渡されると、常に重複を生成します。

たとえば、 _.union( [ { a:1 } ], [ { a:1 } ])[ { a:1 }, { a:1 } ]を返します

逆に、アンダースコア自体のisEqual関数は、問題のオブジェクトが等しいことを示します。 使用する等価比較を指示するフラグ/オプション、またはコンパレータを渡すオプションがあるかもしれません。

change

最も参考になるコメント

このスレッドは、自分のコードで比較のカスタマイズを処理するために、 _.intersectionWith_.differenceWith_.unionWith 、および_.uniqWithを追加するように促しました。

var array = [ { 'a': 1, 'b': 2 }, { 'a': 1, 'b': 3 }, { 'a': 1, 'b': 2 } ];

_.uniqWith(array, _.isEqual);
// => [{ 'a': 1, 'b': 2 }, { 'a': 1, 'b': 3 }]

全てのコメント32件

まだ比較機能を受け入れていないのには驚きました。 :+1:

これは、差分、共通部分、一意など、他のすべての配列計算関数に適用されることを指摘しておく価値があります。

配列関数の完全なスイートを更新して、オブジェクトに異なる等式コンパレータを使用できるようにするとよいでしょう。

_.union()関数に渡すことができるブールパラメータ値に基づいて等式を比較するオプションがあるとしたら、もっと簡単ではないでしょうか。 trueの場合、その配列内のすべてのオブジェクトを自動的に比較します。

たとえば、 _.union([1, 2, 3, 10, [{a:1}, {a:1}]], true)[1,2,3,10, {a:1}]を出力します

@ amiral84いいえ。それは無関係です。 その動作が必要な場合は、flattenを使用して結合を構成します。

@michaelficarraでは、このトピックの要点を見逃しましたか? :NS

@ amiral84そうですね。 機能のリクエストは、最初のコメントで完全かつ簡潔に説明されています。

_.unionは、一意でフラット化するための単なるラッパー関数であるため、根本的な問題は_.uniqようです。

_.union = restArgs(function(arrays) {
  return _.uniq(flatten(arrays, true, true));
});

このスレッドは、自分のコードで比較のカスタマイズを処理するために、 _.intersectionWith_.differenceWith_.unionWith 、および_.uniqWithを追加するように促しました。

var array = [ { 'a': 1, 'b': 2 }, { 'a': 1, 'b': 3 }, { 'a': 1, 'b': 2 } ];

_.uniqWith(array, _.isEqual);
// => [{ 'a': 1, 'b': 2 }, { 'a': 1, 'b': 3 }]

または_.isCollectionに沿った何かで、コレクションを扱っているかどうかを判断します。 コレクションを扱う場合には、比較が使用する必要があります_.isEqualの代わりに===コレクションの場合には良いもしませんています。

@dperrymorrow

コレクションの場合には役に立たない===代わりに_.isEqualを使用する必要があります。

動的スイッチングは悪い考えのように聞こえます。 JSは、多くのことに===またはSameValueZero比較を使用します。 これらの比較の外に出る必要がある場合は、 _.uniqWithようなもので十分です。

この@jdaltonのおかげで、あなたが言及した_opWith関数は、私が達成しようとしていることに完全に完璧です。 それらがリリースによっていつ利用可能になるかについて何か考えはありますか?

@jdaltonは比較の良い点ですが、通常、アンダースコアにオブジェクト間の全体的な違いを検出させるのではなく、コレクションで一意のキーを使用しませんか?

以下は@ wilhen01の要求を解決しませんか_(必要以上に冗長ですが)_

_.chain([{ a: 1 }]).union( [{a: 1}]).unique('a').value();
//=> [{a: 1}]

以下は@ wilhen01の要求を解決しませんか(必要以上に冗長ですが)

_.uniqすでにそれをサポートしています。

そうです、それが私のポイントです。上記のコードは現在、投稿されたとおりに機能します。
ユニオンの結果のキーを使用して、uniq / uniqueを呼び出すことはできませんか?

@dperrymorrowその例の少し外側を考えて、別のプロパティを追加します

わかりました、落とし穴、ごめんなさい...私は好戦的であろうとはしていません、ただ問題を完全に理解したかっただけです。 _.uniqWith関数でプルリクエストを送信したいと思います。

心配ありません、それはラッドでしょう。

_.intersectionWith、_。differenceWith、_。unionWith、および_.uniqWith

4つの新しい関数を作成する代わりに、オプションで比較関数を最後の引数として渡すことができるのは、より優れたAPIではないでしょうか。

@jashkenas

4つの新しい関数を作成する代わりに、オプションで比較関数を最後の引数として渡すことができるのは、より優れたAPIではないでしょうか。

はい、できますが、 _.uniqようなメソッド非常に過負荷になっているため、複雑になります。 これは、この状況にはあまりにも賢いと感じるアリティスニッフィングを導入することを意味します。 これはまた、実装を単純化して別々のメソッドに分割できる場合、多くのオプション機能を1つのポイントにバンドルするため、将来のモジュール化の取り組みを複雑にします。

そうです、まったく残念な設計上の問題です。 しかし、コンパレータを許可するためだけに新しい関数を作成することも、適切な解決策のようには思えません。

さて、追加の比較関数パラメーターがここに行く方法ですか?
もしそうなら、プルリクエストを更新できます。

私が予測する唯一のトリッキーな部分は、前述の@jdaltonのように、パラメーターの解析をもう少し毛深いものにすること

_.uniq = _.unique = function(array, isSorted, iteratee, context) {
  if (!_.isBoolean(isSorted)) {
    context = iteratee;
    iteratee = isSorted;
    isSorted = false;
  }
//...

おそらく、isSorted _.isFunctionかどうかを確認するためのチェックを追加して、それをコンパレータとして扱います。

@jashkenas

しかし、コンパレータを許可するためだけに新しい関数を作成することも、適切な解決策のようには思えません。

それは悪い状況のための最良の選択肢かもしれません。 私は最近、オーバーロードされた機能を分割することを始めましたが、その結果にはかなり満足しています。 APIサーフェスが増加しますが、 maxByuniqBypickBy 、またはuniqWithunionWithなどの同様のテーマのメソッドのより簡単な実装とグループ化が可能になります。 zipWith 、またはsortedIndexBysortedIndexOfsortedUniquniqの場合、現時点ではまだ共有ベース関数を使用していますが。

このプルリクエスト#2368に感謝します。

私は:+1: uniqByまたはuniqWithです。 私はuniqさらに過負荷にすることに完全に反対します(#2368が現在提案されているため)

:+1: @megawacuniqBy

Fwiw lodashは、コンパレータのカスタマイズを可能にするために、 _.uniq(array, iteratee)の分割形式としてuniqByを使用し、形式として_.uniqWithを使用します。

ええ、考え直してuniqWithの方がいい名前です

それでは、別の方法でLodashのリクエストをプルする必要がありますか?
2つのプロジェクトが統合されたと思いましたが、間違っていますか?

@dperrymorrow

別の方法でLodashのリクエストをプルする必要があります

必要ありません、彼らはすでにlodashのエッジマスターブランチにいます。

2つのプロジェクトが統合されたと思いましたが、間違っていますか?

まだ。 Lodash v4は、マージのアイデアのいくつかを証明しています。

@jdalton他のiterateeとの_.uniqWith実装について、もう少し詳しく説明していただけますか。

@Pavnii
もちろん。 lodash / npm / _baseUniqをチェックアウトできます。
comparatorが渡されると、 arrayIncludes (アンダースコアのcontains )の代わりにarrayIncludes arrayIncludesWithヘルパーを使用してチェックが実行されます。

@jdaltonそれは私を助けます。

このページは役に立ちましたか?
0 / 5 - 0 評価

関連する問題

jdalton picture jdalton  ·  4コメント

markvr picture markvr  ·  3コメント

clouddueling picture clouddueling  ·  3コメント

jezen picture jezen  ·  8コメント

githublyp picture githublyp  ·  3コメント