【问题标题】:Using List<string>.Any() to find if a string contains an item as well as find the matching item?使用 List<string>.Any() 查找字符串是否包含项目以及找到匹配的项目?
【发布时间】:2017-03-28 13:54:36
【问题描述】:

我有一个字符串列表,可以将其视为“过滤器”。

例如:

List<string> filters = new List<string>();
filters.Add("Apple");
filters.Add("Orange");
filters.Add("Banana");

我有另一个字符串列表,其中包含句子。

例子:

List<string> msgList = new List<string>();
msgList.Add("This sentence contains the word Apple.");
msgList.Add("This doesn't contain any fruits.");
msgList.Add("This does. It's a banana.");

现在我想找出 msgList 中的哪些项目包含水果。为此,我使用以下代码:

foreach(string msg in msgList)
{
    if(filters.Any(msg.Contains))
    {
        // Do something.
    }
}

我想知道,在 Linq 中是否有一种方法可以使用类似于 List.Any() 的方法来检查 msgList 是否包含水果,如果包含,还可以获取与查询匹配的水果。如果我可以在“过滤器”中获得匹配的索引,那应该没问题。也就是说,对于循环的第一次迭代它应该返回 0('Apple' 的索引),对于第二次迭代返回 null 或类似负值的东西,对于第三次迭代它应该返回 2('Banana' 的索引) .

我在 SO 和 Google 中进行了检查,但找不到我正在寻找的确切内容。

【问题讨论】:

  • Banana 字符串与banana 不同。您需要不区分大小写的搜索吗?
  • msgList.Add("What if I like apples, oranges, and bananas?");
  • 史蒂夫,是的,你是对的。我真的不介意这种情况,但假设不区分大小写更好。
  • 格特,很好看。我想我应该更好地提出我的问题,因为我的实际消息列表中的任何单个字符串都只包含一个“水果”。我确实希望 'bananas' 返回 true,因为 'banana' 是一个子字符串。
  • 在这种情况下,将您的msg.Contains 更改为filter =&gt; msg.IndexOf(filter, StringComparison.OrdinalIgnoreCase) &gt;= 0),这将使.Contains 不区分大小写。如果你看at the source for bool Contains(string value),你会发现它只是return ( IndexOf(value, StringComparison.Ordinal) &gt;=0 );

标签: c# string linq list any


【解决方案1】:

你想要FirstOrDefault 而不是 Any。

FirstOrDefault 如果找到则返回第一个匹配的对象,如果未找到则返回默认值(通常为 null)。

【讨论】:

  • 完美!这正是我所需要的。谢谢。
【解决方案2】:

您可以使用List&lt;T&gt;.Find 方法:

foreach (string msg in msgList)
{
    var fruit = filters.Find(msg.Contains);
    if (fruit != null)
    {
        // Do something.
    }
}

【讨论】:

  • 这也解决了问题,谢谢!我刚刚接受了 Gabriel Luci 的回答,因为他领先你一分钟。 :D
【解决方案3】:
List<string> filters = new List<string>() { "Apple", "Orange", "Banana" };

string msg = "This sentence contains the word Apple.";

var fruit = Regex.Matches(msg, @"\w+", RegexOptions.IgnoreCase)
            .Cast<Match>()
            .Select(x=>x.Value)
            .FirstOrDefault(s => filters.Contains(s));

【讨论】:

  • 我不希望得到回应,但是.. @downvoter 有什么问题?你不喜欢什么?
  • 没有 dv,但问题要求更多(尽管其他原因可能是 dv-ed)
  • L.B.,我试过了,但这似乎不能解决我的问题。
  • @Sach 它返回了什么?你期待什么?
  • @L.B 它返回 null。我不确定这是否是因为这是我用来解释问题的简化示例,但是我的“过滤器”可以包含带有空格的单词(例如,说“猕猴桃”),而且我的 msgList 可以包含类似“这句话包含猕猴桃”之类的内容。理想情况下,这应该返回字符串“猕猴桃”。
【解决方案4】:

返回元素索引的可能方法

foreach (string msg in msgList)
{
   var found = filters.Select((x, i) => new {Key = x, Idx = i})
                      .FirstOrDefault(x => msg.Contains(x.Key));
   Console.WriteLine(found?.Idx);
}

还请注意,包含区分大小写,因此香蕉字符串与香蕉字符串不匹配。如果您想要不区分大小写,可以将 IndexOf 与 StringComparison 运算符一起使用

【讨论】:

    猜你喜欢
    • 2020-11-29
    • 2023-03-27
    • 2013-03-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-21
    • 1970-01-01
    相关资源
    最近更新 更多