2012-04-04 6 views
96

私は次のようにresultlistに格納されたリストを持っている:c# - リストからアイテムを削除するにはどうすればよいですか?

var resultlist = results.ToList(); 

それはどのように私は、リストからID 2を削除するには、この

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

ようになりますか?

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(); 

答えて

188

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

RemoveAt(int index)は、商品のインデックスを知っている場合に使用できます。たとえば、次のように

resultlist.RemoveAt(1); 

それとも、Remove(T item)使用することができます:あなたはアイテムが本当にあなたがSingleOrDefaultを使用することができますが存在するかわからない場合は

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

を。 SingleOrDefaultは、アイテムがない場合はnullを返します(Singleはアイテムが見つからない場合に例外をスローします)。重複した値がある場合は両方ともスローされます(2つのアイテムは同じidです)。

var itemToRemove = resultlist.SingleOrDefault(r => r.Id == 2); 
if (itemToRemove != null) 
    resultList.Remove(itemToRemove); 
+3

、おそらく 'var itemsToRemove = resultlist.Where(r => r.Id == 2);よりも、 foreach(ItemsToRemoveのvar itemToRemove)resultList.Remove(itemToRemove); ' – Vlad

+0

これは' resultlist.Items.RemoveAt(1); 'ではないでしょうか? – Obsidian

29
resultList = results.Where(x=>x.Id != 2).ToList(); 

正確にインデックス。

+1

もう1つの同様のアプローチ(述語を使用する)は 'List.FindIndex' /' List.RemoteAt'(突然変異操作であるという "良い"または "あまりうれしい"機能を持っています)を使用することです。 –

+0

Trueですが、Listの操作*が*変更されているということに注意してください。 Listはシーンの背後にある配列を使用し、必要と思われる場合は、容量を小さくしたり、大きくしたりして配列を再作成することができます。 *通常*、削除は既存の配列のインプレース変異です。 – KeithS

+0

これはスレッドセーフではありません。その単純さのために、SingleOrDefaultを使用するだけで静的メソッドに含める必要はありません。 –

0

...またはちょうどresultlist.RemoveAt(1)は、あなたが知っている場合:私はそれが実現するのは簡単ですし、読むために少し楽に「ない」条件でクエリを作ることができるような小さなLINQのヘルパーがあります

+2

は、IDでソートされている場合のみ表示されます。 – zzzzBov

3

あなたはRemoveAt(index)方法、またはRemove(obj)方法のいずれかを使用することができ、リストの種類が、一般的なリストを指定しない:

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

// RemoveAt(index) 
resultList.RemoveAt(1); 
4

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

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

、(ガードと結合)FindIndexは等、そこのIDにギャップがあるか、または順序が間違っている場合RemoveAtが正しいことが保証されます、そして(Remove VS)RemoveAtを使用する Oを回避(n)リストを検索する。

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 

ハッピーコーディング:ここ

LINQPadスニペットです。

8

短い答え:
results.RemoveAll(r => r.ID==2);ID resultsで2(代わりに)で項目を削除します。

詳細な回答:

私はあなたが削除するアイテムのIDのリストを持つことができるので、.RemoveAll()を使用する方が簡単だと思う - 次の例を考えてください。

お持ちの場合:

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" }, 
    new myClass() { ID=2, FirstName="John", LastName="Wilson" }, 
    new myClass() { ID=3, FirstName="Doug", LastName="Berg" }, 
    new myClass() { ID=4, FirstName="Bill", LastName="Wilson" }, 
}; 

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

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

そして、単にこれを使用して削除してください:

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

項目2及び3を除去し、アイテム1と4を維持する - removeListによって指定されるように。 注:は、これが発生したため、追加の義務は必要ありません。もちろん

、あなたはまた、のような単一の項目にそれを使用することができます。

それは私たちの例では、ID 4で法案を削除します
results.RemoveAll(r => r.ID==4); 


DotNetFiddle:Run the demo

2

より簡略化:

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

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