比较 C# 中的字符串片段并从集合中删除项目

Posted

技术标签:

【中文标题】比较 C# 中的字符串片段并从集合中删除项目【英文标题】:Comparing pieces of strings in C# and removing items from collection 【发布时间】:2017-10-18 05:56:13 【问题描述】:

我有一段用 C# 编写的代码,如下所示:

foreach (var item in allNegatives)

    for (int index = 0; index < _items.Count(); index++)
    
        if (_items[index].Title.ToLower().IndexOf(item, StringComparison.OrdinalIgnoreCase) >= 0)
        
            _items.RemoveAt(index);
        
    

_items 集合是一个字符串列表(长标题)......现在你可以看到我有一个 foreach 循环和一个 for 循环,用于检查 _items 集合中的标题是否包含“否定”的短语。否定短语只是意味着如果标题包含它,我想从集合中删除该项目...

这里的问题是这不能按我想要的方式工作......?

如果我收藏了 100 件物品,其中一些是这样的:

Samsung galaxy s8 1200 mAh

Samsung galaxy s8 1200 mAh

Samsung galaxy s7 1200 mAh

Samsung galaxy s7 1200 mAh

Samsung galaxy s6 1200 mAh

如果否定短语是:

S8 and S7

我得到的输出是:

Samsung galaxy s7 1200 mAh

Samsung galaxy s7 1200 mAh

Samsung galaxy s6 1200 mAh

由于某种原因,似乎第二次 foreach 循环包含该短语的项目没有从集合中删除,我不确定为什么。

有人可以帮帮我吗?

【问题讨论】:

在您给出的示例中,您是否要删除所有 Title 包含 S7S8 的项目? Title.ToLower().IndexOf(item, StringComparison.OrdinalIgnoreCase) 如果你使用OrdinalIgnoreCase,那么使用ToLower 是没有意义的。如果要忽略大小写,则无需创建新的小写字符串。 @StephenMuecke 集合中包含 S8 或 S7 的任何项目 @TimSchmelter 是的,好点,完全忘记了! :) 您可以只使用.Contains() 来获取要删除的项目,然后使用.RemoveAll() 【参考方案1】:

John 已经解释了为什么它不能那样工作,你正在迭代所有索引,并且在这个循环中你正在删除项目。这可能会导致不正确的结果或异常。

也许你想使用List.RemoveAll

_items.RemoveAll(i => allNegatives.Any(n => i.Title.IndexOf(n, StringComparison.OrdinalIgnoreCase) >= 0));

这也避免了使用Title.ToLower,如果你使用OrdinalIgnoreCase,这是不必要的。

【讨论】:

是的,RemoveAll 可能是最干净的方法。【参考方案2】:

您正在跳过项目。

想象一下这个列表:

0 s5
1 s8 <-
2 s7
3 s6

您位于索引 1。S8 匹配,因此您将其从列表中删除,现在看起来像这样:

0 s5
1 s7 <-
2 s6

您仍在索引 1 处,但它现在包含 s7。您进行迭代,现在您处于 2。即使 s7 匹配,您也已跳过它。

如果你向后迭代,这不会发生:

foreach (var item in allNegatives)

  for (int index = _items.Count() - 1; index >= 0; --index)
  
      if (_items[index].Title.IndexOf(item, StringComparison.OrdinalIgnoreCase) >= 0)
      
        _items.RemoveAt(index);
      
   

【讨论】:

【参考方案3】:

为此使用 LINQ。以下是如何执行此操作的示例:

List<string> list= new List<string>()

    "Samsung galaxy s8 1200 mAh",
    "Samsung galaxy s8 1200 mAh",                
    "Samsung galaxy s7 1200 mAh",
    "Samsung galaxy s7 1200 mAh",
    "Samsung galaxy s6 1200 mAh"
;
List<string> negativePhrs= new List<string>()"s7","s8";
list = list.Where(x=> !negativePhrs.Any(y=> x.ToLower().Contains(y.ToLower()))).ToList();
foreach(var a in list)

    Console.WriteLine(a);

【讨论】:

【参考方案4】:

我不确定您要做什么。您要从 items 或 allNegatives 中删除吗?

这是你想做的吗?

var things = new List<Thing> new Thing  Title="Bob", new Thing Title="Carol", new Thing Title="Dave", new Thing Title="Alice" ;
var items = new List<string> "foo", "bar", "Alice", "Dave";
var result = items.Where(x => !things.Exists(y => y.Title == x)).Select(z=>z);

打印出来

foreach(var r in result)
   Console.WriteLine(r);

foo
bar

所以它从项目中删除了 Alice 和 Dave,因为它们是事物中的标题。但我想也许你想从事物中移除?

【讨论】:

以上是关于比较 C# 中的字符串片段并从集合中删除项目的主要内容,如果未能解决你的问题,请参考以下文章

XSS:如何从 C# 中的字符串中删除 JS 片段?

用另一个列表替换主活动中的列表并从视图中删除旧列表

从集合中删除文档并从另一个集合中的数组中删除 Id

sql多表查询出来的数据在C#中用啥装载比较好,是泛型集合还是集合??还有其他的可以装吗??

如何通过C#中的特定片段从句子中提取整个单词?

比较 2 个向量并从第 2 个向量中删除第 1 个中找不到的元素 - c++ [关闭]