从列表中删除元素最有效的方法是什么<;T>;在c#中做foreach?
我想知道在进行foreach时,用c#从列表中删除元素的最佳方法是什么 下面是一个代码示例。首先,我创建了一个包含一些元素的列表,然后删除一个:从列表中删除元素最有效的方法是什么<;T>;在c#中做foreach?,c#,C#,我想知道在进行foreach时,用c#从列表中删除元素的最佳方法是什么 下面是一个代码示例。首先,我创建了一个包含一些元素的列表,然后删除一个: List<int> foo = new List<int>(); foo.Add(1); foo.Add(2); foo.Add(3); foreach (int i in foo) { if (i==2) { foo.Remove(i); } } List foo=new List()
List<int> foo = new List<int>();
foo.Add(1);
foo.Add(2);
foo.Add(3);
foreach (int i in foo)
{
if (i==2)
{
foo.Remove(i);
}
}
List foo=new List();
foo.Add(1);
foo.Add(2);
foo.Add(3);
foreach(foo中的int i)
{
如果(i==2)
{
foo.删除(i);
}
}
当我运行这个时,我得到了一个
invalidoOperationException
,但是如何用性能方法解决这个问题呢?为什么需要一个循环
foo.Remove(2);
如果必须在枚举时删除条目,请向后遍历列表,并删除需要删除的项
for (var i = foo.Count-1 ; i >= 0 ; i--) {
if (MustBeRemoved(foo[i])) {
foo.RemoveAt(i);
}
}
请注意,如果您的帖子知道需要删除的值,则不需要这样做。您可以将要删除的项目添加到临时列表中,然后在循环后删除它们:
List<int> foo = new List<int>();
foo.Add(1);
foo.Add(2);
foo.Add(3);
List<int> remove = new List<int>();
foreach (int i in foo) {
if (i==2) {
remove.Add(i);
}
}
foreach (int i in remove) {
foo.Remove(i);
}
List foo=new List();
foo.Add(1);
foo.Add(2);
foo.Add(3);
List remove=新列表();
foreach(foo中的int i){
如果(i==2){
删除。添加(i);
}
}
foreach(移除中的int i){
foo.删除(i);
}
您不能在迭代列表时对其进行编辑
考虑:
List<int> foo;
int[] bar = foo.ToArray();
foreach(int i in bar)
{
if (i == 2)
{
foo.Remove(i);
}
}
列出foo;
int[]bar=foo.ToArray();
foreach(单位:巴)
{
如果(i==2)
{
foo.删除(i);
}
}
但是要注意:你应该向后看这个列表,因为从foo列表中删除一个项目将意味着酒吧列表不再与之对齐。(如果不向后走,就必须跟踪删除次数并调整传递给删除调用的索引!)我认为最好的方法是使用简单的
for
循环向后迭代
for(int i = foo.Count-1; i>=0; i--)
if(foo[i]==2) foo.RemoveAt(i);
更改您的foreach,如下所示
foreach (int i in new List<int>(foo))
foreach(新列表中的int i(foo))
我假设您的实际用例比您所列出的更复杂。所以,让我们假设您实际上有一些条件,适用于每个元素,并且多个元素可以满足。我们称之为谓词
List
公开允许您提供谓词的RemoveAll
方法。然后删除与该谓词匹配的任何项。比如说
Func<int, bool> isEven = i => i % 2 == 0;
List<int> ints = ...
ints.RemoveAll(item => isEven(item));
// ints will only contain odd numbers
Func isEven=i=>i%2==0;
列表整数=。。。
ints.RemoveAll(item=>isEven(item));
//整数将只包含奇数
其他要考虑的方法是在<<代码>后面的列表中遍历循环并按索引移除,构建包含要删除的项的第二个列表,然后在第二个列表中的第二个循环中,从第一个项目中删除项。或者,您可以编写一个查询来构造一个新的序列,其中包含您希望保留的项。
如果您想删除任意元素,而不仅仅是一个元素,您可以使用RemoveAll
并指定一个谓词:
foo.RemoveAll(element => (element == 2));
如果您决定不使用for和foreach;) 因此,你应该问什么是正确的,而不是性能。解决了这个难题之后,再担心它是否有效。我同意@AnthonyPegram。在谈到性能时,您还需要确定是内存受限还是处理器受限——答案各不相同。您的问题是“我想在这堵墙上钻一个洞;用锤子做这件事最快的方法是什么?”最快的方法是首先不使用锤子。foreach循环不是作业的正确工具;问如何使用错误的工具更快地解决问题并不是一个富有成效的问题。我假设他过于简化了他的示例:)我猜他只是给出了一个非常简化的示例。这是一个非常简单的示例,在实际代码中,它一定更复杂。所以这不是work@ThomasLevesque真正的代码看起来像
foo.RemoveAll(i=>i==2)代码>。您给出的示例无法编译,因为List.RemoveAll
没有接受t
参数的重载。@phoog,这不是我写的,其他人编辑了我的答案。。。我将把它回滚到以前的状态。foo.RemoveAll(MustBeRemoved)
如果需要删除许多元素,性能会更好。注意:此代码不枚举列表。它使用的是索引变量,而不是枚举数。不允许在枚举列表时编辑列表,这将导致异常:在mscorlib.dll中发生“System.InvalidOperationException”类型的未处理异常。其他信息:集合已修改;枚举操作可能无法执行。如果.NET版本支持此操作,我将在“通过数组反向循环”方法上面使用此方法。它更干净,代码更少,可读性更强,更不容易出错。
foo.RemoveAll(x => x == 2);