3

(「removeall where」または「removeall two argument predicate」のキーワードに基づいて可能な限り多くの検索を行ったが、運が悪かったので、ここに行く)

問題は、(Class Wave の) オブジェクトのリストと関係関数を次のように持っていることです: private bool AinB(Wave A, Wave B)、A が B に「ある」場合に true を返します。また、AinB(x,y) は true です。 AinB(y,x) が false であることを保証します。

オブジェクトがリスト内の別のオブジェクトに「ある」リスト内のすべてのオブジェクトを削除する最良の方法は何ですか? つまり、削除後、リストには、リスト内の他のオブジェクトと「含まれる」関係にないオブジェクトのみを含める必要がありますか?

理想的には、これは次のように簡単に実行できます。

listX.RemoveAll( (x,y) => AinB(x,y)) ですが、もちろんこれは C# では合法ではありません。x と y のどちらを削除するかを簡単に指定する方法もありません。

インデックスを使用してリストをループすることを考えました

int i = listX.Count - 1;
while (i>=0)
{
    int r = listX.RemoveAll(X => AinB(X, listX[i]));
    i = i - r - 1;
}

これは機能しているようですが、問題を解決するためのストレートなlinqコードを使用するより良い方法があるかどうか疑問に思っています。ありがとう。

4

3 に答える 3

0

リストの最上位の要素から最下位の要素まで検査する通常の for ループを使用します。リスト内の重複がないか現在の位置にある要素を調べ、見つかった場合は現在の要素を削除します (場合によってはイテレータを減らします)。

例:

List<string> stuff = new List<string>(); //full of stuff
for(int i = stuff.Count - 1; i > 0; i--)
{
    //Edited here for more efficiency.
    for (int x = i - 1; x > 0; x--)
    {
        if (stuff[x] == stuff[i])
        {
            stuff.RemoveAt(i);
            break; //or possibly continue;
        }
    }
}

これはここで手作業でコーディングされているため、いくつかの構文エラーがある可能性があります。何かが正しくないことがわかった場合は、遠慮なく編集してください。

LINQ のウィザードである場合は、リスト内のオブジェクトをグループ化し、出力リストの各グループの最初のオブジェクトを選択することもできます..

于 2013-06-27T13:05:22.297 に答える
-2

LINQ Except 呼び出しを使用できます。

List a = new List();
a.Add("a");
a.Add("b");
a.Add("c");
List b = new List();
b.Add("b");
b.Add("c");
b.Add("d");
List c = a.Except(b);

リスト c には項目「a」のみが含まれます。

比較オブジェクトを与えることで、さらに賢くすることもできます。

List c = a.Except(b, new CompareObject());
于 2013-06-27T12:59:41.627 に答える