如何从c#列表中删除项目?

我有一个列表存储在resultlist如下:

var resultlist = results.ToList();

它看起来是这样的:

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

我如何从列表中删除ID 2 ?

843483 次浏览
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();

... 或者resultlist.RemoveAt(1),如果你知道确切的索引。

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

如果你知道项目的索引,可以使用RemoveAt (int指数)。例如:

resultlist.RemoveAt(1);

或者你可以使用删除(T项目):

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

当你不确定项目是否存在时,你可以使用SingleOrDefault。如果没有项目,SingleOrDefault将返回null(当Single找不到项目时将抛出异常)。当存在重复值(两个具有相同id的项)时,两者都会抛出。

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

你没有指定哪种类型的列表,但是泛型列表可以使用RemoveAt(index)方法,也可以使用Remove(obj)方法:

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


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

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

虽然我会可能使用KeithS提供的解决方案(只是简单的Where/ToList),但这种方法的不同之处在于它变异原始列表对象。这可能是好事(也可能是坏事)“特性”取决于期望。

在任何情况下,FindIndex(加上一个保护)确保在id中有空白或顺序错误等情况下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

快乐的编码。

< p > 简短的回答:
Remove (from list results) < / >强

results.RemoveAll(r => r.ID == 2);将在results中删除带有ID 2的项(到位)。

Filter(未从原始列表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); }
如果你调用这个函数两次,你认为会发生什么? 像< / p >
myRemove(); myRemove();

第一次呼叫将在第一个和最后一个位置删除比尔,第二次呼叫将删除道格,名单中只剩下约翰·威尔逊。


由于c#版本8,你也可以写results[^1]而不是var last = results.Count() - 1;results[last]:

void myRemove()  =>  results.RemoveAll(r => results[^1].FirstName == r.FirstName);
所以你将不再需要局部变量last(参见索引和范围)。此外,由于它是一行程序,所以不需要花括号,可以使用=>代替。 有关c#中所有新特性的列表,请查看在这里.


DotNetFiddle: 运行演示

更多的简化:

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

不需要创建一个新的var对象。

{
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}");
}


}


}
}

试试下面的代码:

resultlist.Remove(resultlist.Find(x => x.ID == 2));