使用LINQ进行部分匹配比较两个列表[英] Compare two Lists using Linq for partial matches

本文是小编为大家收集整理的关于使用LINQ进行部分匹配比较两个列表的处理/解决方法,可以参考本文帮助大家快速定位并解决问题,中文翻译不准确的可切换到English标签页查看源文。

问题描述

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

我有两个List<string>

他们中有代码.一个是所选代码的列表,一个是所需代码的列表.整个代码列表是一棵树,因此它们具有子代码.一个例子是 代码b 代码B.1 代码B.11

因此,可以说所需的代码为b,但是树下的任何内容都可以满足该要求,因此,如果选定的代码为A和C部分匹配.

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

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

我遇到的错误是在必需的.

对不起,如果这令人困惑,请告诉我是否添加任何其他信息会有所帮助.

推荐答案

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

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条件应为您提供匹配的元素 - 我不确定您是否应该使用StartsWith或Contains,这取决于您的要求.

其他推荐答案

如果选择并且所需列表足够大,以下速度比接受的答案快:

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.Count和m = required.Count接受的答案算法复杂性是O(n*m).但是,我建议的内容具有更好的算法复杂性:O((n+m)*Log(n))

其他推荐答案

此查询找到两个列表中存在的任何匹配.如果两个列表中都存在一个值,则它返回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));

本文地址:https://www.itbaoku.cn/post/1556980.html

问题描述

I tried looking through some of the other questions, but couldn't find any that did a partial match.

I have two List<string>

They have codes in them. One is a list of selected codes, one is a list of required codes. The entire code list is a tree though, so they have sub codes. An example would be Code B Code B.1 Code B.11

So lets say the Required code is B, but anything under it's tree will meet that requirement, so if the Selected codes are A and C the match would fail, but if one of the selected codes was B.1 it contains the partial match.

I just need to know if any of the selected codes partially match any of the required codes. Here is my current attempt at this.

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

The error I get is on the Required.Any() and it's cannot convert from bool to string.

Sorry if this is confusing, let me know if adding any additional information would help.

推荐答案

I think you need something like this:

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);
        }
    }
}

Applying the Any condition on required in this way should give you the elements that match - I'm not sure if you should use StartsWith or Contains, that depends on your requirements.

其他推荐答案

If selected and required lists are large enough the following is faster than the accepted answer:

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);
    }
}

Given n = required.Count and m = required.Count the accepted answer algorithm complexity is O(n*m). However what I propose has a better algorithm complexity: O((n+m)*Log(n))

其他推荐答案

This query finds any match that exists in two lists. If a value exists in both lists, it returns true, otherwise 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));