使用 Linq 比较两个列表以进行部分匹配
Compare two Lists using Linq for partial matches
我尝试查看其他一些问题,但找不到任何部分匹配的问题。
我有两个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 转换为 string。
抱歉,如果这让您感到困惑,请告诉我添加任何其他信息是否有帮助。
我想你需要这样的东西:
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);
}
}
}
以这种方式在 required
上应用 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))
此查询查找两个列表中存在的任何匹配项。如果两个列表中都存在一个值,则它 returns 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));
我尝试查看其他一些问题,但找不到任何部分匹配的问题。
我有两个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 转换为 string。
抱歉,如果这让您感到困惑,请告诉我添加任何其他信息是否有帮助。
我想你需要这样的东西:
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);
}
}
}
以这种方式在 required
上应用 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))
此查询查找两个列表中存在的任何匹配项。如果两个列表中都存在一个值,则它 returns 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));