我如何将字符串与“;过滤器”;linq中的列表

本文关键字:过滤器 linq 列表 字符串 | 更新日期: 2023-09-27 18:25:10

我正在尝试通过"filter"列表筛选字符串集合。。。一大堆脏话。字符串包含列表中的一个单词我不想要它。

到目前为止,这里的坏词是"frakk":

string[] filter = { "bad", "words", "frakk" };
string[] foo = 
{ 
    "this is a lol string that is allowed", 
    "this is another lol frakk string that is not allowed!"
};
var items = from item in foo 
            where (item.IndexOf( (from f in filter select f).ToString() ) == 0)
            select item;

但这不起作用,为什么?

我如何将字符串与“;过滤器”;linq中的列表

您可以使用Any+Contains:

var items = foo.Where(s => !filter.Any(w => s.Contains(w)));

如果您想不区分大小写进行比较:

var items = foo.Where(s => !filter.Any(w => s.IndexOf(w, StringComparison.OrdinalIgnoreCase) >= 0));

更新:如果要排除筛选列表中至少有一个单词的句子,可以使用String.Split()Enumerable.Intersect:

var items = foo.Where(sentence => !sentence.Split().Intersect(filter).Any());

Enumerable.Intersect非常高效,因为它在引擎盖下使用了Set。把长序列放在第一位更有效。由于Linq的延迟执行,is在第一个匹配字上停止。

(请注意,"空"Split包括其他空白字符,如tab或换行符)

您需要解决的第一个问题是将句子分解成一系列单词。最简单的方法是基于空间

string[] words = sentence.Split(new char[] {' '}, StringSplitOptions.RemoveEmptyEntries);

从那里你可以使用一个简单的LINQ表达式来查找亵渎

var badWords = words.Where(x => filter.Contains(x));

然而,这是一个有点原始的解决方案。它不会处理许多复杂的情况,你可能需要考虑

  • 有许多字符可以作为空格。我的解决方案仅使用' '
  • 拆分不处理标点符号。因此dog!不会被视为dog。在法律字符上拆字可能要好得多

您最初尝试失败的原因是这一行:

(from f in filter select f).ToString()

计算为linq表达式部分所暗示的数组迭代程序类型名称的字符串。所以你实际上是在比较以下字符串的字符:

System.Linq.Enumerable+WhereSelectArrayIterator``2[System.String,System.String]

而不是在检查短语时过滤器中的单词。