我正在尝试创建一个删除所有Sales对象的方法,如果它们的字符串中包含“TJ”的材质描述。我的问题是,当我创建一个包含四个Sales的List时,其中两个在其描述中包含“TJ”,只删除一个。被删除的那个并不是第一个独有的。如果我从第一个销售中删除“TJ”,则第二个销售将被正确删除。为什么会这样?我的方法,以及TestCase如下。
/// <summary>
/// This method deletes all sales with a 'TJ' material.
/// </summary>
public void deleteTJ()
{
for (int i = 0; i < salesList.Count; i++)
{
if (salesList[i].material.Contains("TJ"))
{
salesList.Remove(salesList[i]);
Console.WriteLine("FOUND IT");
}
else
{
Console.WriteLine("Not this time");
}
}
}
[TestMethod]
public void TestDeleteTJ()
{
sale1.material = "ABJFSJTJ"; // Contains TJ
sale2.material = "KTJANDKFH"; // Contains TJ
sale3.material = "SADVUAWDJ"; // No TJ
sale4.material = "JTNDBAYK"; // No TJ
testList.Add(sale1);
testList.Add(sale2);
testList.Add(sale3);
testList.Add(sale4);
Modifier modifier = new Modifier(testList);
Assert.IsTrue(testList.Count == 4);
modifier.deleteTJ();
Assert.IsTrue(testList.Count == 2);
Assert.AreEqual("SADVUAWDJ", testList[0]);
Assert.AreEqual("JTNDBAYK", testList[1]);
}
答案 0 :(得分:3)
这是因为您在循环期间编辑列表。一旦删除一个项目,计数就会被更改。
有两种方法 - 使用其中一种方法:
以相反的顺序循环( List.Count-1到0 ):
for (int i = salesList.Count - 1; i >= 0; i--)
{
}
使用Lambdas删除值
salesList.RemoveAll(s => s.material.Contains("TJ"));
答案 1 :(得分:1)
当您从列表中删除项目时,所有后续索引都会递减。
0: ABJFSJTJ
1: KTJANDKFH
2: SADVUAWDJ
3: JTNDBAYK
删除第一个索引时,列表现在如下所示:
0: KTJANDKFH
1: SADVUAWDJ
2: JTNDBAYK
循环然后将i
递增到1,有效地跳过之前在索引1处的内容。
答案 2 :(得分:1)
你的问题源于你的循环。
CLUSTER
因此,在您的代码中,您正在从集合中删除索引。但问题是,你是否正在迭代数组。所以你可以通过以下两种方式解决:
示例1:
for(int index = 0; index < collection.Count; index++)
if(collection[index].Contains("TJ")
collection.Remove(...)
示例2:
var filter = collection;
for(int index = 0; index < collection.Count; index++)
if(collection[index].Material.Contains("TJ"))
filter.Remove(..);
示例3:
var filter = collection.Where(item => !item.Material.Contains("TJ"));