使用Linq比较两个列表以进行部分匹配

时间:2015-09-22 06:57:15

标签: c# linq contains

我试着查看其他一些问题,但找不到任何部分匹配。

我有两个List<string>

他们有代码。一个是所选代码的列表,一个是所需代码的列表。整个代码列表虽然是树,所以它们有子代码。一个例子是 代码B. 代码B.1 代码B.11

所以我们说必需的代码是B,但是它下面的任何代码都符合这个要求,所以如果选择的代码是A和C,那么匹配就会失败,但是如果所选的代码之一是B.1,它包含部分匹配。

我只需要知道所选代码是否与任何所需代码部分匹配。这是我目前的尝试。

//Required is List<string> and Selected is a List<string>
int count = (from c in Selected where c.Contains(Required.Any()) select c).Count();

我得到的错误是在Required.Any()上,它无法从bool转换为字符串。

很抱歉,如果这令人困惑,请告诉我们是否添加任何其他信息会有所帮助。

3 个答案:

答案 0 :(得分:5)

我认为你需要这样的东西:

using System;
using System.Collections.Generic;
using System.Linq;

static class Program {
    static void Main(string[] args) {
        List<string> selected = new List<string> { "A", "B", "B.1", "B.11", "C" };
        List<string> required = new List<string> { "B", "C" };
        var matching = from s in selected where required.Any(r => s.StartsWith(r)) select s;
        foreach (string m in matching) {
            Console.WriteLine(m);
        }
    }
}

以这种方式在Any上应用required条件应该会为您提供匹配的元素 - 我不确定您是否应该使用StartsWithContains ,这取决于你的要求。

答案 1 :(得分:1)

如果选中且必需的列表足够大,则以下内容比接受的答案快:

static void Main(string[] args)
{
    List<string> selected = new List<string> { "A", "B", "B.1", "B.11", "C" };
    List<string> required = new List<string> { "B", "C" };
    required.Sort();
    var matching = selected.Where(s =>
    {
        int index = required.BinarySearch(s);
        if (index >= 0) return true; //exact match
        index = ~index;
        if (index == 0) return false;
        return s.StartsWith(required[index - 1]);
    });
    foreach (string m in matching)
    {
        Console.WriteLine(m);
    }
}

鉴于n = required.Countm = required.Count,接受的答案算法复杂度为O(n*m)。然而,我建议的算法复杂度更高:O((n+m)*Log(n))

答案 2 :(得分:0)

此查询查找两个列表中存在的任何匹配项。如果两个列表中都存在值,则返回true,否则返回false

List<string> listString1 = new List<string>();
List<string> listString2 = new List<string>();

listString1.Add("A");
listString1.Add("B");
listString1.Add("C");
listString1.Add("D");
listString1.Add("E");

listString2.Add("C");
listString2.Add("X");
listString2.Add("Y");
listString2.Add("Z");

bool isItemExist = listString1.Any(x => listString2.Contains(x));