我需要在字符串之间进行相交但要比较子字符串:
public class MiNumeroEqualityComparer : IEqualityComparer<string> {
public bool Equals(string x, string y) => x.Contains(y);
public int GetHashCode(string obj) => obj.GetHashCode();
}
List<string> lst = new List<string> { "abcXdef", "abcXdef", "abcede", "aYcde" };
List<string> num = new List<string> { "X", "Y", "Z" };
var fin = lst.Intersect(num, new MiNumeroEqualityComparer());
我希望使用fin:“ abcXdef”,“ abcXdef”,“ aYcde”
但是它是空的,为什么?
首先,我尝试使用不区分大小写的子字符串:(也没有成功)
public bool Equals(string x, string y) => x.IndexOf(y, StringComparison.InvariantCultureIgnoreCase) >= 0;
但是也是空的。
答案 0 :(得分:3)
您正在做两个列表之间的交集,这将为您提供它们之间的通用项。由于这两个列表都没有包含相同的项目,因此您没有任何结果。
如果您要从lst
获取包含num
项的所有项,则可以执行以下代码,该代码使用they added an optimization to avoid the creation of bound methods方法来过滤来自lst的项目:
var fin = lst.Where(item => num.Any(item.Contains));
结果:
{“ abcXdef”,“ abcXdef”,“ aYcde”}
或者,如果您确实要执行不区分大小写的查询,则可以改用IndexOf
方法:
var fin = lst.Where(item => num.Any(n =>
item.IndexOf(n, StringComparison.OrdinalIgnoreCase) >= 0));
如果这很难理解(有时是Linq),则上面的第一个代码段是编写以下内容的简便方法:
var fin = new List<string>();
foreach (var item in lst)
{
foreach (var n in num)
{
if (item.Contains(n))
{
fin.Add(item);
break;
}
}
}
答案 1 :(得分:1)
确定Rufus已在提供的答案中解决了您的问题。但是,让我解释一下您的方法为何行不通的原因。
产生空结果的原因是因为将永远不会调用Equals(string x, string y)
。它可以根据GetHashCode
方法来推导不等式。如果哈希值相同,则它将调用Equals
。换句话说,您在Equals
中的逻辑将永远不会执行。
这是一些代码,因此您可以查看发生了什么。
class Program
{
static void Main(string[] args)
{
// See I added an item at the end here to show when Equals is called
List<string> lst = new List<string> { "abcXdef", "abcXdef", "abcede", "aYcde", "X" };
List<string> num = new List<string> { "X", "Y", "Z" };
var fin = lst.Intersect(num, new MiNumeroEqualityComparer()).ToList();
Console.ReadLine();
}
}
public class MiNumeroEqualityComparer : IEqualityComparer<string>
{
public bool Equals(string x, string y)
{
Console.WriteLine("Equals called for {0} and {1}.", x, y);
return x.Contains(y);
}
public int GetHashCode(string obj)
{
Console.WriteLine("GetHashCode alled for {0}.", obj);
return obj.GetHashCode();
}
}
如果运行上面的代码,它将仅对产生相同哈希的项目调用Equals
;因此仅适用于“ X”。
请参见this fiddle中的输出。
答案 2 :(得分:0)
相交从2个集合中获取公共元素。这里的Intersect方法很优雅。它可以用于多种类型的元素。
您的结果为空,因为它不是列表中的通用值。
List<string> lst = new List<string> { "abcXdef", "abcXdef", "abcede", "aYcde" };
List<string> num = new List<string> { "X", "Y", "abcXdef", "Z", "aYcde" };
var fin = lst.Intersect(num);
fin >> abcXdef,aYcde