70

私は次のコードを持っています:

List<string> test1 = new List<string> { "@bob.com", "@tom.com" };
List<string> test2 = new List<string> { "joe@bob.com", "test@sam.com" };

@bob.comまたは@tom.comを持つtest2の人を削除する必要があります。

私が試したことはこれです:

bool bContained1 = test1.Contains(test2);
bool bContained2 = test2.Contains(test1);

bContained1 = falseしかしbContained2 = true。各リストをループするのではなく、Linqクエリを使用してデータを取得したいと思います。bContained1は、以下で作成したLinqクエリの条件と同じです。

List<string> test3 = test1.Where(w => !test2.Contains(w)).ToList();

上記のクエリは完全一致では機能しますが、部分一致では機能しません。

私は他のクエリを見てきましたが、Linqでこれとの密接な比較を見つけることができます。どんなアイデアでも、あなたが私に指摘できるところならどこでも、大きな助けになるでしょう。

4

9 に答える 9

105
var test2NotInTest1 = test2.Where(t2 => test1.Count(t1 => t2.Contains(t1))==0);

ティムの提案によるより速いバージョン:

var test2NotInTest1 = test2.Where(t2 => !test1.Any(t1 => t2.Contains(t1)));
于 2012-09-29T21:34:13.050 に答える
20
bool doesL1ContainsL2 = l1.Intersect(l2).Count() == l2.Count;

L1とL2は両方ともList<T>

簡単な説明は次のとおりです。2つの反復可能オブジェクトの結果の交差が小さいリスト(ここではL2)と同じ長さである場合、すべての要素が大きいリスト(ここではL1)に存在する必要があります。

于 2017-08-03T08:12:27.887 に答える
15
var output = emails.Where(e => domains.All(d => !e.EndsWith(d)));

または、必要に応じて:

var output = emails.Where(e => !domains.Any(d => e.EndsWith(d)));
于 2012-09-29T21:39:25.560 に答える
5

これを行うための拡張メソッドがすでに存在するため、ここでこのようにLinqを使用する必要はありません。

Enumerable.Except<TSource>

http://msdn.microsoft.com/en-us/library/bb336390.aspx

必要に応じて比較するために、独自の比較器を作成する必要があります。

于 2012-09-29T21:32:22.467 に答える
3

このようなもの:

List<string> test1 = new List<string> { "@bob.com", "@tom.com" };
List<string> test2 = new List<string> { "joe@bob.com", "test@sam.com" };

var res = test2.Where(f => test1.Count(z => f.Contains(z)) == 0)

実例:ここ

于 2012-09-29T21:37:03.200 に答える
2
List<string> test1 = new List<string> { "@bob.com", "@tom.com" };
List<string> test2 = new List<string> { "joe@bob.com", "test@sam.com", "bets@tom.com" };

var result = (from t2 in test2
              where test1.Any(t => t2.Contains(t)) == false
              select t2);

クエリフォームが使用したいものである場合、これは読みやすく、多かれ少なかれ「パフォーマンス」が高い可能性があります。

つまり、実行しようとしているのはO(N * M)アルゴリズムです。つまり、N個のアイテムをトラバースして、それらをM個の値と比較する必要があります。必要なのは、最初のリストを1回だけトラバースし、必要な回数だけ他のリストと比較することです(最悪の場合は、ブラックリストにあるすべてのドメインと比較する必要があるため、電子メールが有効な場合です)。

from t2 in testメーリングリストを1回ループします。

test1.Any(t => t2.Contains(t)) == falseブラックリストと比較し、1つの一致リターンが見つかった場合(したがって、必要がない場合はリスト全体と比較しません)

select t2きれいなものを保管してください。

だからこれが私が使うものです。

于 2012-09-29T21:40:12.080 に答える
0

次のことを試してください。

List<string> test1 = new List<string> { "@bob.com", "@tom.com" };
List<string> test2 = new List<string> { "joe@bob.com", "test@sam.com" };
var output = from goodEmails in test2
            where !(from email in test2
                from domain in test1
                where email.EndsWith(domain)
                select email).Contains(goodEmails)
            select goodEmails;

これは、提供されているテストセットで機能します(正しく見えます)。

于 2012-09-29T21:34:19.967 に答える
-3

これが最も簡単な方法だと思います。

test1.ForEach(str => test2.RemoveAll(x=>x.Contains(str)));
于 2015-01-04T15:54:14.853 に答える
-3
List<string> l = new List<string> { "@bob.com", "@tom.com" };
List<string> l2 = new List<string> { "joe@bob.com", "test@bob.com" };
List<string> myboblist= (l2.Where (i=>i.Contains("bob")).ToList<string>());
foreach (var bob in myboblist)
    Console.WriteLine(bob.ToString());
于 2016-02-28T15:52:24.017 に答える