比较 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
包含 S7
或 S8
的项目?
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# 中的字符串片段并从集合中删除项目的主要内容,如果未能解决你的问题,请参考以下文章