239

我有一个存储在 resultlist 中的列表,如下所示:

var resultlist = results.ToList();

它看起来像这样:

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

如何从列表中删除 ID 2?

4

8 回答 8

452

List<T>有两种方法可以使用。

如果您知道项目的索引,则可以使用RemoveAt(int index) 。例如:

resultlist.RemoveAt(1);

或者您可以使用Remove(T item)

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

当您不确定该项目是否真的存在时,您可以使用SingleOrDefault。如果没有项目SingleOrDefault将返回(当找不到项目时将抛出异常)。当存在重复值(具有相同的两个项目)时,两者都会抛出。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,第二个元素的索引为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); }

如果你调用这个函数两次,你认为会发生什么?像

myRemove(); myRemove(); 

第一个调用将删除第一个和最后一个位置的 Bill,第二个调用将删除 Doug,并且只有 John Wilson 留在列表中。


注意:C# 版本 8开始,您也可以编写results[^1]代替var last = results.Count() - 1;and results[last]

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

因此,您不再需要局部变量last(请参阅indices 和 range)。此外,由于它是单行的,因此您不需要花括号并且可以使用它=>。有关 C# 中所有新功能的列表,请查看此处


DotNetFiddle:运行演示

于 2016-02-15T14:50:03.293 回答
49
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();
于 2012-04-04T20:45:02.617 回答
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 回答
6

更简化:

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

无需创建新的 var 对象。

于 2016-05-06T20:08:06.297 回答
5

还有另一种方法。它使用List.FindIndexList.RemoveAt

虽然我可能使用 KeithS 提供的解决方案(只是简单的/WhereToList,但这种方法的不同之处在于它会改变原始列表对象。根据期望,这可能是一个好的(或坏的)“功能”。

在任何情况下,如果 ID 中存在间隙或排序错误等, FindIndex(加上保护)RemoveAt将确保正确,并且使用RemoveAt(vs Remove) 可以避免在列表中进行第二次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

快乐编码。

于 2012-04-04T21:00:11.960 回答
0

...或者只是resultlist.RemoveAt(1)如果您确切地知道索引。

于 2012-04-04T20:46:48.003 回答
-1
{
    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}");
            }

        }

    }
}
于 2019-07-24T06:24:50.747 回答