C#のリストからアイテムを削除する方法


189

次のように、resultlistにリストを保存しています。

var resultlist = results.ToList();

次のようになります。

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

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

回答:


364

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戻りnullます(アイテムSingleが見つからない場合は例外がスローされます)。両方とも、重複する値(同じの2つの項目id)がある場合にスローされます。

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

5
まあ、多分var itemsToRemove = resultlist.Where(r => r.Id == 2); foreach (var itemToRemove in ItemsToRemove) resultList.Remove(itemToRemove);
Vlad

1
これはいけませんresultlist.Items.RemoveAt(1);か?
DreamTeK 2016年

48

短い答え:
削除(リストからresults

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

フィルター(元のリストから削除せずに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" },
    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これは場所で起こるので、必要な追加のassigmentがないこと。

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

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

この例では、ID 4のBillを削除します。


DotNetFiddle:デモを実行する


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

Linqヘルパーが少しあります。これは実装が簡単で、 "where not"条件でクエリを少し読みやすくすることができます。

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

1
(述語を使用する)別の同様のアプローチは、List.FindIndex/ を使用するList.RemoteAtことです。

真実ですが、リストの操作変化していると言うことに注意してください。Listは舞台裏で配列を使用し、必要に応じて配列を小さい容量または大きい容量で再作成できます。通常、削除は既存のアレイのインプレース変異です。
KeithS 2012

このありえないスレッドセーフでは、とあなただけSingleOrDefaultを使用することができ、そのシンプルさのために、それは必要性をdoesntの静的メソッドに含有させる

スレッドセーフであると誰も言っていない(そしてそれがスレッドが何をすることに依存しているかに依存する;実際に1つの並行コレクションですべてを動作させるのではなく、ワーカースレッドに別のメモリ内構成体を与えることが望ましいかもしれない) )、そしてOP は述語と一致するレコードを除くすべてのレコード必要とするため、SingleOrDefaultは実際には必要のないものを正確に返します。「静的メソッド」は実際、ほとんどのLinqと同様に拡張メソッドであり、不要なもの(1つまたは複数)を定義する方が、実行するよりも簡単な場合に機能します。
KeithS 2013

5

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

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

いずれの場合でも、FindIndex(ガードと組み合わせて)は、RemoveAtIDにギャップがある場合や順序が間違っている場合などに正しいものであることを保証し、RemoveAt(vs Remove)を使用すると、リスト全体の2番目の O(n)検索を回避できます。

ここで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

ハッピーコーディング。


4

どのようなリストを指定するかは指定しませんが、汎用リストはRemoveAt(index)メソッドまたはメソッドのいずれかを使用できますRemove(obj)

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

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


0

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


0
{
    class Program
    {
        public static List<Product> list;
        static void Main(string[] args)
        {

            list = new List<Product>() { new Product() { ProductId=1, Name="Nike 12N0",Brand="Nike",Price=12000,Quantity=50},
                 new Product() { ProductId =2, Name = "Puma 560K", Brand = "Puma", Price = 120000, Quantity = 55 },
                 new Product() { ProductId=3, Name="WoodLand V2",Brand="WoodLand",Price=21020,Quantity=25},
                 new Product() { ProductId=4, Name="Adidas S52",Brand="Adidas",Price=20000,Quantity=35},
                 new Product() { ProductId=5, Name="Rebook SPEED2O",Brand="Rebook",Price=1200,Quantity=15}};


            Console.WriteLine("Enter ProductID to remove");
            int uno = Convert.ToInt32(Console.ReadLine());
            var itemToRemove = list.Find(r => r.ProductId == uno);
            if (itemToRemove != null)
                list.Remove(itemToRemove);
            Console.WriteLine($"{itemToRemove.ProductId}{itemToRemove.Name}{itemToRemove.Brand}{itemToRemove.Price}{ itemToRemove.Quantity}");
            Console.WriteLine("------------sucessfully Removed---------------");

            var query2 = from x in list select x;
            foreach (var item in query2)
            {
                /*Console.WriteLine(item.ProductId+" "+item.Name+" "+item.Brand+" "+item.Price+" "+item.Quantity );*/
                Console.WriteLine($"{item.ProductId}{item.Name}{item.Brand}{item.Price}{ item.Quantity}");
            }

        }

    }
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.