34


4

順序を考慮に入れずに、2つのシーケンスに同じ項目が含まれているかどうかを調べるために使用できる、組み込みのlinqメソッドというものはありますか?

例えば:

{1、2、3} == {2、1、3} {1、2、3}!= {2、1、3、4} {1、2、3}} = {1、2、4}

あなたはSequenceEqualsを持っています、しかしそれから私は最初に両方のシーケンスを注文しなければならないでしょう、私ではないですか?

7 Answer


36


いくつかの方法があります。 AとBがIEnumerableだとします。

!A.除外(B)。すべて()


9


2つのIEnumerable(AとB)がある場合:

bool equal =(A.Count()== B.Count()

Excep全体は評価されないので、これはExcept(A).Countよりも優れていると思います。 Exceptに1つの要素が見つかるとすぐに停止します。 Countを使用すると、Except全体が評価されます。 これに加えて、最初にCountプロパティをチェックするだけで、これらの高価なExceptの評価を避けることができます。 カウントが等しくない場合は、例外を確認します。


4


重複が気にならない場合 あなたは `{1、2、3}`を `{1、2、3、2}`と等しいと考えるでしょう:)

new HashSet(A).SetEquals(B)

(あるいは `int`ではなく、どんな型でも要素型です)。

さもないと:

public static bool SequenceEqualUnordered(IEnumerable first, IEnumerable second)
{
    if (first == null)
        return second == null; // or throw if that's more appropriate to your use.
    if (second == null)
        return false;   // likewise.
    var dict = new Dictionary(); // You could provide a IEqualityComparer here if desired.
    foreach(T element in first)
    {
        int count;
        dict.TryGetValue(element, out count);
        dict[element] = count + 1;
    }
    foreach(T element in second)
    {
        int count;
        if (!dict.TryGetValue(element, out count))
            return false;
        else if (--count == 0)
            dict.Remove(element);
        else
            dict[element] = count;
    }
    return dict.Count == 0;
}

最初のシーケンスの各要素の集計をしてから、それに対して2番目の要素をチェックします。 2番目のシーケンスで1つが多すぎると、falseを返すことができます。それ以外の場合は、集計の辞書に同等のものが残っていない場合、または要素が残っている場合はfalseです。

2つのO(n log n)の種類の `OrderBy()`に続けてO(n)比較を使用するのではなく、O(n)演算で一連の集計を作成し、O(n)をチェックします。それ。


3


HashSetクラスを試してください。

var enumA = new [] {1、2、3、4}; var enumB = new [] {4、3、1、2};

var hashSet = new HashSet(enumA); hashSet.SymmetricExceptWith(enumB); Console.WriteLine(hashSet.Count == 0); // true =>等しい

しかし、それは値が異なる場合にのみ正しく機能します。

例えば

var enumA = new [] {1、1、1、2}; var enumB = new [] {1、2、2、2};

上記の方法と「等しい」とも見なされます。


1


私はあなたがこれを達成することができる最も早い方法は順序を注文することであると思います。


1


私は重複のないコレクションに新しい項目をマージするためにこれをしました、それは2つのコレクションを取り、重複なしですべての項目を返します

リストnonMatching =(newCampaignsのnから!ここで!(Existingのeからの選択e.Id).Contains(n.Id)の選択n).ToList();

今すぐ削除して! containsステートメントの

リストnonMatching =(newCampaignsのnから)ここで(Existing eのeから).Contains(n.Id)nの選択).ToList();

それは重複を返します


0


もしあなたが本当に重複があるかどうかを確かめるためだけにテストしているのなら、leppieの提案はうまくいくはずです。

if(A.除外(B).Count == 0

しかし、重複することなくIEnumerableに到達する必要があるだけの場合は、次のようにします。

var result = A.Union(B).Distinct();