如何检查列表是否包含另一个列表中的所有字符串

3

我有一个对象列表。该对象包含一个字符串列表,类似于:

Original Answer:最初的回答

public class ObjectA
{
    ...
    IList<string> StringList;
}

我有一个单词列表需要在StringList上搜索。我需要在ObjectA列表中进行搜索,并找到所有包含所有单词(所有单词的部分)的ObjectA。

因此,我做了以下操作:

最初的回答:

 List<ObjectA> myObjectList;
 List<string> wordsToFind;  

 var result = myObjectList.Where(objectA => wordsToFind.All(objectA.StringList.Contains));

我的问题是结果只包含完整单词(相等)。我希望得到包含我的wordsToFind部分的结果。

示例

wordsToFind = {"tes","don"};
StringListElement = {"test", "done"}

应该在我的选择上返回。

我该怎么做呢?


列表a是否包含列表b中的所有单词?顺序如何?是完全匹配吗? - Maytham Fahmi
顺序无关紧要 - Paul
如果您能提供一个最小可复现示例(MCVE),那将非常棒。请确保提供样本输入以及基于这些样本输入的预期结果。 - mjwills
你想进行序数比较吗?https://dev59.com/P3RB5IYBdhLWcg3w1Khe#498722 - mjwills
3个回答

5

IndexOf可能是你想使用的方法之一,或者它的重载版本。

返回指定 Unicode 字符或字符串在此实例中第一个匹配项的从零开始的索引。如果未找到该字符或字符串,则该方法返回 -1。

List<ObjectA> myObjectList;
List<string> wordsToFind;  

var result = myObjectList.Where(x => x.StringList.All(y => wordsToFind.Any(z => y.IndexOf(z) >= 0)));

需要注意的是,这个算法的时间复杂度非常糟糕。


更新

完整演示点此查看

另外需要注意的是,如果您想要不区分大小写,请使用

y.IndexOf(z, StringComparison.InvariantCultureIgnoreCase) 

或者以下其中之一:
  • CurrentCulture 使用与当前区域设置相关的排序规则和当前区域设置来比较字符串。

  • CurrentCultureIgnoreCase 使用与当前区域设置相关的排序规则、当前区域设置以及忽略被比较字符串的大小写来比较字符串。

  • InvariantCulture 使用与不变文化相关的排序规则来比较字符串。

  • InvariantCultureIgnoreCase 使用与不变文化相关的排序规则、不变文化以及忽略被比较字符串的大小写来比较字符串。

  • Ordinal 使用序号(二进制)排序规则来比较字符串。

  • OrdinalIgnoreCase 使用序号(二进制)排序规则以及忽略被比较字符串的大小写来比较字符串。


谢谢,性能应该不是问题,我猜列表都很小。我喜欢你的建议,但它总是返回空结果,我不知道为什么。 - Paul
2
@Paul 添加了在线演示 - TheGeneral
谢谢详细说明...我想我对我的需求解释错误了。我的搜索结果中的所有单词都必须在我的列表中,但是我的StringList可以包含不在我的搜索结果中的单词。我修改了您的示例,应该返回两个对象:https://dotnetfiddle.net/QqshRh - Paul
1
我修改了你的代码,现在它运行得很好!https://dotnetfiddle.net/z7Q3eW谢谢 - Paul
@Paul 谢谢,我刚才睡着了呵呵,我会修正答案以便未来的读者。 - TheGeneral

1

要做到这一点,可以使用AnyAll的组合。

您需要检查wordsToFind所有元素是否是StringList中的任何元素的子字符串。

bool result = wordsToFind.All(word => currentObject.StringList.Any(str => str.Contains(word));

这是针对对象列表中的一个对象。您可以再次将All应用于该列表。

0

我觉得这个对你应该有效

var wordsToFind = new List<string>{ "tes","don"};
var data= new List<ObjectA>()
{
    new ObjectA()
    {
        StringList = new List<string>{"test", "done", "blah"}
    },
    new ObjectA()
    {
        StringList = new List<string>{"test2", "done2", "blah2"}
    }
};

var result = (from item in data.Select(x => x.StringList)
              from bar in item
              from word in wordsToFind
              where bar.Contains(word)
              select bar)
              .ToList();

结果应该给你

"test", "done","test2", "done2"

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接