2013-05-17 23 views
8

LINQを使用して別のIListに基づいてIListから特定の要素を削除する方法。 IDがlist2にあるlist1からレコードを削除する必要があります。 は以下IListから特定の要素を削除するLINQ <int>

class DTO 
{ 

    Prop int ID, 
    Prop string Name 
} 

IList<DTO> list1; 

IList<int> list2; 



foreach(var i in list2) 
{ 
    var matchingRecord = list1.Where(x.ID == i).First(); 
    list1.Remove(matchingRecord); 
} 

これは、私はそれをやっている方法です同じことを行うには良い方法があり、コードサンプルです。

+6

似たような質問がない日はありません。 –

+0

Linqを使用しないでください。 Linqは、コレクションを変更するのではなく、新しいシーケンスをフィルタリングして作成することです。 –

答えて

8

あなたが単純なためWhereを使用することができます。

list1 = list1.Where(x => !list2.Contains(x.ID)) 
      .ToList(); 

をしかし、あなたは本当に私はこのアプローチを使用することになりDanielHilgarthの答え

+3

RemoveAllはリストを返しません。削除されたアイテムの数を表すintを返します。 –

+0

@RobertJ .:私の答えを編集 –

+0

@RobertJ。あなたはRemoveAllを使用する必要があります、私の答えを参照してください –

12

@好む、場所で削除する必要があります。

var itemsToRemove = list1.Where(x => list2.Contains(x.ID)).ToList(); 
foreach(var itemToRemove in itemsToRemove) 
    list1.Remove(itemToRemove); 

このアプローチアイテムを削除します。 list1に多くのアイテムがあり、list2には数が少ない場合に最適です。
list1list2の項目の量が似ている場合は、Cuong Leのアプローチが適しています。

+1

なぜ 'Where'の後に' ToList() 'を実行するのですか?それが必要だとは思わないでください。 –

+2

@GeorgeDuckett:うん、それは必要です。それ以外の場合、 'itemsToRemove'は' list1'を繰り返し処理します。 'Remove'と一緒に' InvalidOperationException'を生成します:*コレクションが変更されました。列挙操作が実行されない可能性があります* –

+0

ああ、良い点、それについて忘れてしまった。 –

11

IList<T>の「RemoveAll()」拡張メソッドは、List.RemoveAll()とまったく同じように動作します。 (これは一般的なクラスライブラリを保つために十分に一般的に有用である。)例えば

(エラーは明確にするため取り除かチェック、あなたはパラメータがnullではありません確認する必要があると思います):次に

public static class IListExt 
{ 
    public static int RemoveAll<T>(this IList<T> list, Predicate<T> match) 
    { 
     int count = 0; 

     for (int i = list.Count - 1; i >= 0; i--) 
     { 
      if (match(list[i])) 
      { 
       ++count; 
       list.RemoveAt(i); 
      } 
     } 

     return count; 
    }   

list1から必要なアイテムを削除するには、実際には次のように簡単になります:

list1.RemoveAll(item => list2.Contains(item.ID)); 
関連する問題