239

次のように結果リストにリストが保存されています。

var resultlist = results.ToList();

これは次のようになります。

ID FirstName  LastName
-- ---------  --------
1  Bill       Smith
2  John       Wilson
3  Doug       Berg

リストからID2を削除するにはどうすればよいですか?

4

8 に答える 8

452

List<T>には 2 つの方法があります。

アイテムのインデックスがわかっている場合は、 RemoveAt(int index)を使用できます。例えば:

resultlist.RemoveAt(1);

または、 Remove(T item)を使用できます:

var itemToRemove = resultlist.Single(r => r.Id == 2);
resultList.Remove(itemToRemove);

アイテムが実際に存在するかどうかわからない場合は、SingleOrDefaultを使用できます。アイテムがない場合SingleOrDefaultは返されます (アイテムが見つからない場合は例外がスローされます)。重複する値 (同じ を持つ 2 つの項目) がある場合、両方がスローされます。nullSingleid

var itemToRemove = resultlist.SingleOrDefault(r => r.Id == 2);
if (itemToRemove != null)
    resultList.Remove(itemToRemove);
于 2012-04-04T20:47:55.503 に答える
79

簡単な答え:
削除 (リストからresults)

results.RemoveAll(r => r.ID == 2);ID 2のアイテムをresults(インプレースで)削除します。

フィルター (元のリストから削除せずにresults):

var filtered = result.Where(f => f.ID != 2);ID 2のアイテムを除くすべてのアイテムを返します

詳細な回答:

.RemoveAll()削除したいアイテム ID のリストを持つことができるので、非常に柔軟だと思います。次の例を参考にしてください。

あなたが持っている場合:

class myClass {
    public int ID; public string FirstName; public string LastName;
}

次のようにいくつかの値を割り当てresultsます。

var results = new List<myClass> {
    new myClass { ID=1, FirstName="Bill", LastName="Smith" },   // results[0]
    new myClass { ID=2, FirstName="John", LastName="Wilson" },  // results[1]
    new myClass { ID=3, FirstName="Doug", LastName="Berg" },    // results[2]
    new myClass { ID=4, FirstName="Bill", LastName="Wilson" }   // results[3]
};

次に、削除する ID のリストを定義できます。

var removeList = new List<int>() { 2, 3 };

そして、これを使用してそれらを削除するだけです:

results.RemoveAll(r => removeList.Any(a => a==r.ID));

で指定されているように、アイテム 2 と 3 を削除し、アイテム 1 と 4 を保持しますremoveListこれはその場で行われるため、追加の割り当ては必要ありません。

もちろん、次のような単一のアイテムにも使用できます。

results.RemoveAll(r => r.ID==4);

この例では、ID 4 の Bill が削除されます。

最後に言及することは、リストにはインデクサーがあることです。つまり、動的配列のようにアクセスすることもできます。つまりresults[3]、結果リストの 4 番目の要素が返されます (最初の要素のインデックスは 0、2 番目の要素のインデックスは1など)。

したがって、最初の名前が結果リストの 4 番目の要素と同じであるすべてのエントリを削除する場合は、次のように簡単に実行できます。

results.RemoveAll(r => results[3].FirstName == r.FirstName);

その後、John と Doug だけがリストに残り、Bill は削除されることに注意してください (例の最初と最後の要素)。重要なのは、リストが自動的に縮小されるため、残りの要素は 2 つだけであるため、この例で RemoveAll を実行した後に許可される最大のインデックスは 1
(つまりresults.Count() - 1) です。

トリビア: この知識を使用して、ローカル関数を作成できます。

void myRemove()  { var last = results.Count() - 1; 
                   results.RemoveAll(r => results[last].FirstName == r.FirstName); }

この関数を 2 回呼び出すとどうなると思いますか? お気に入り

myRemove(); myRemove(); 

最初の呼び出しで Bill が最初と最後の位置から削除され、2 回目の呼び出しで Doug が削除され、John Wilson だけがリストに残ります。


注: C# バージョン 8以降では、 and results[^1]の代わりに次のように書くこともできます。var last = results.Count() - 1;results[last]

void myRemove()  =>  results.RemoveAll(r => results[^1].FirstName == r.FirstName); 

したがって、ローカル変数はもう必要ありlastません ( indexs and rangesを参照してください)。さらに、これはワンライナーであるため、中括弧は必要なく、=>代わりに使用できます。C# のすべての新機能の一覧については、こちらを参照してください


DotNetFiddle:デモを実行する

于 2016-02-15T14:50:03.293 に答える
49
resultList = results.Where(x=>x.Id != 2).ToList();

実装が簡単で、「どこにない」条件のクエリを少し読みやすくすることができる、私が気に入っている小さなLinqヘルパーがあります。

public static IEnumerable<T> ExceptWhere<T>(this IEnumerable<T> source, Predicate<T> predicate)
{
    return source.Where(x=>!predicate(x));
}

//usage in above situation
resultList = results.ExceptWhere(x=>x.Id == 2).ToList();
于 2012-04-04T20:45:02.617 に答える
6

より単純化:

resultList.Remove(resultList.Single(x => x.Id == 2));

新しい var オブジェクトを作成する必要はありません。

于 2016-05-06T20:08:06.297 に答える
6

リストの種類は指定しませんが、一般的な List はRemoveAt(index)メソッドまたはメソッドのいずれかを使用できますRemove(obj)

// Remove(obj)
var item = resultList.Single(x => x.Id == 2);
resultList.Remove(item);

// RemoveAt(index)
resultList.RemoveAt(1);
于 2012-04-04T20:49:47.873 に答える
5

別のアプローチがあります。と を使用List.FindIndexList.RemoveAtます。

私はおそらくKeithSによって提示されたソリューション (単純なWhere/のみToList) を使用するでしょうが、このアプローチは元のリスト オブジェクトを変更するという点で異なります。これは、期待に応じて、良い (または悪い) "機能" になる可能性があります。

いずれにせよ、FindIndex(ガードと結合された) はRemoveAt、ID にギャップがある場合や順序が間違っている場合などに が正しいことを保証し、 RemoveAt(vs ) を使用すると、リスト内での2 回目のO(n) 検索Removeが回避されます。

LINQPadスニペットは次のとおりです。

var list = new List<int> { 1, 3, 2 };
var index = list.FindIndex(i => i == 2); // like Where/Single
if (index >= 0) {   // ensure item found
    list.RemoveAt(index);
}
list.Dump();        // results -> 1, 3

ハッピーコーディング。

于 2012-04-04T21:00:11.960 に答える
0

...またはresultlist.RemoveAt(1)インデックスを正確に知っている場合。

于 2012-04-04T20:46:48.003 に答える