【问题标题】:Removing a node from a list using a for使用 for 从列表中删除节点
【发布时间】:2014-05-29 20:38:37
【问题描述】:

这是我所做的:

// this is an example of my function, the string and the remover should be variables
string delimeter = ",";
string remover="4";
string[] separator = new string[] { "," };
List<String> List = "1,2,3,4,5,6".Split(separator, StringSplitOptions.None).ToList();
for (int i = 0; i < List.Count - 1; i++)
{
    if(List[i]==remover)
        List.RemoveAt(i);
}
string allStrings = (List.Aggregate((i, j) => i + delimeter + j));
return allStrings;

问题是返回的字符串和原来的字符串一样,和“1,2,3,4,5,6”一样。 “4”还在里面。

如何解决?

编辑:

解决方案是我没有检查列表的最后一个节点,因为这是我刚刚给出的示例

【问题讨论】:

  • 附注:你有i &lt; List.Count - 1,但这永远不会打到最后一项。这是你的意图吗?
  • 你有一个错误和@Bradley所说的......
  • @Silvermind 就是这样,非常感谢!

标签: c# list split


【解决方案1】:

当你从这样的列表中删除项目时,你应该让你的 for 循环反向运行,从最高索引到最低索引。

如果您从最低到最高,您最终会在移除项目时将它们向下移动,这将跳过项目。反向运行就没有这个问题了。

【讨论】:

  • 由于 OP 的示例没有连续两个 4s,但这里不会咬他。
  • 这是一个很好的提示,我找到了我的错误谢谢!
  • @Cooper 这是 a 错误,但不是导致您的代码无法工作的错误。
【解决方案2】:

就目前而言,您的代码会产生预期的输出。运行时它将返回1,2,3,5,6。如果不是,那是由于您调用此方法的方式存在错误。

这并不是说你没有问题。

当您删除一个项目时,您仍然会增加当前索引,因此您在删除任何项目后跳过检查该项目。

虽然有很多解决方案,但这里最好的解决方案是使用ListRemoveAll 方法。它不仅可以确保评估所有项目,而且可以更有效地进行评估。从列表中删除一个项目意味着将所有项目移动一个。 RemoveAll 可以在最后完成所有的转换,如果删除了很多项目,效率会更高。

您遇到的另一个错误是您的 for 循环根本不会检查最后一项。

附带说明,您不应该使用Aggregate 将一堆字符串连接在一起,并给出分隔符。 非常效率低下,因为您需要在添加第二项时将所有数据从第一项复制到一个中间字符串中,然后在添加第三项时将这两个数据都复制到一个新字符串中,然后所有三个 those 在创建第四个字符串时转换为新字符串,依此类推。相反,您应该使用string.Join(delimeter, List);,它不仅方式 更高效,而且更容易编写并且在语义上准确地代表了您正在尝试做的事情。双赢。

我们现在可以将方法重写为:

string delimeter = ",";
string remover = "4";
List<String> List = "1,2,3,4,5,6"
    .Split(new[] { delimeter }, StringSplitOptions.None).ToList();
List.RemoveAll(n => n == remover);
return string.Join(delimeter, List);

另一种选择是避免创建一个列表只是为了从中删除项目,然后再次聚合数据。相反,我们可以只取我们拥有的项目序列,只取出我们想要保留的项目,而不是删除我们不想保留的项目,然后聚合它们。这在功能上是相同的,但是省去了构建列表和删除项目的不必要的工作,从需求中提取机制:

string delimeter = ",";
string remover = "4";
var items = "1,2,3,4,5,6"
        .Split(new[] { delimeter }, StringSplitOptions.None)
        .Where(n => n != remover);
return string.Join(delimeter, items);

【讨论】:

  • 我的错误是我没有检查 for 中的最后一个节点,我在示例中似乎没有这样做,因为这是我刚刚给出的示例,非常感谢
【解决方案3】:

用这个来删除

  list.RemoveAll(f => f==remover);

【讨论】:

  • 我认为这是解决问题的方法,因为他们的意图是清除所有符合特定条件的项目。他使用了一个循环,这是不正确的,因为当您删除一个项目时,列表会被更改并且其索引变得无效。 List 类提供了在不使用任何循环的情况下执行此操作的方法。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-02-25
  • 2016-08-13
  • 1970-01-01
  • 2021-03-10
  • 1970-01-01
  • 2021-05-30
  • 1970-01-01
相关资源
最近更新 更多