C#for循环删除包含'TJ'的字符串只删除包含它的一个字符串

时间:2017-06-06 14:54:23

标签: c# visual-studio

我正在尝试创建一个删除所有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]);
    }

3 个答案:

答案 0 :(得分:3)

这是因为您在循环期间编辑列表。一旦删除一个项目,计数就会被更改。

有两种方法 - 使用其中一种方法:

  1. 以相反的顺序循环( List.Count-1到0 ):

    for (int i = salesList.Count - 1; i >= 0; i--)
    {
    }
    
  2. 使用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

因此,在您的代码中,您正在从集合中删除索引。但问题是,你是否正在迭代数组。所以你可以通过以下两种方式解决:

  • 创建您的收藏集的副本,然后从您不会重复的内容中删除。
  • 您可以使用Linq,它会删除所有&#34; TJ&#34;包含集合中的元素。

示例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"));