c#交集和联合不能正常工作
本文关键字:常工作 工作 不能 | 更新日期: 2023-09-27 18:07:51
我在VS 2010中使用c# 4.0,并试图生成n组对象的交集或并集。
下面可以正常工作:
IEnumerable<String> t1 = new List<string>() { "one", "two", "three" };
IEnumerable<String> t2 = new List<string>() { "three", "four", "five" };
List<String> tInt = t1.Intersect(t2).ToList<String>();
List<String> tUnion = t1.Union(t2).ToList<String>();
// this also works
t1 = t1.Union(t2);
// as does this (but not at the same time!)
t1 = t1.Intersect(t2);
然而,下面的内容不是。这些是代码片段。
我的班级是:
public class ICD10
{
public string ICD10Code { get; set; }
public string ICD10CodeSearchTitle { get; set; }
}
IEnumerable<ICD10Codes> codes = Enumerable.Empty<ICD10Codes>();
IEnumerable<ICD10Codes> codesTemp;
List<List<String>> terms;
// I create terms here ----
// and then ...
foreach (List<string> item in terms)
{
// the following line produces the correct results
codesTemp = dataContextCommonCodes.ICD10Codes.Where(e => item.Any(k => e.ICD10CodeSearchTitle.Contains(k)));
if (codes.Count() == 0)
{
codes = codesTemp;
}
else if (intersectionRequired)
{
codes = codes.Intersect(codesTemp, new ICD10Comparer());
}
else
{
codes = codes.Union(codesTemp, new ICD10Comparer());
}
}
return codes;
上面只返回最后一个搜索项的结果。
为了以防万一,我还添加了自己的比较器,但这没有什么区别:
public class ICD10Comparer : IEqualityComparer<ICD10Codes>
{
public bool Equals(ICD10Codes Code1, ICD10Codes Code2)
{
if (Code1.ICD10Code == Code2.ICD10Code) { return true; }
return false;
}
public int GetHashCode(ICD10Codes Code1)
{
return Code1.ICD10Code.GetHashCode();
}
}
我肯定我忽略了一些明显的东西-我只是看不出它是什么!
代码:return codes;
返回一个延迟的枚举对象。没有执行任何查询来填充集合。有些查询在每次循环中都要执行,以便进行计数。
这个延迟执行是一个问题,因为闭包问题…在返回时,item
被绑定到最后一次循环执行。
通过在每次循环执行中强制执行查询来解决这个问题:
if (codes.Count() == 0)
{
codes = codesTemp.ToList();
}
else if (intersectionRequired)
{
codes = codes.Intersect(codesTemp, new ICD10Comparer()).ToList();
}
else
{
codes = codes.Union(codesTemp, new ICD10Comparer()).ToList();
}
如果您正在使用自己的比较器,则应该查看GetHashCode
函数的正确实现。linq操作符也使用这种比较。你可以看看这里:http://msdn.microsoft.com/en-us/library/system.object.gethashcode (v = vs.80) . aspx
您可以尝试将哈希函数更改为"返回0",看看这是否是问题所在。如果它是一个类对象,ICD10Code.GetHashCode
可能会返回不同的值
您的问题肯定不是连接到Intersect
或Union
LINQ扩展方法。我刚刚测试了以下内容:
var t1 = new List<ICD10>()
{
new ICD10() { ICD10Code = "123" },
new ICD10() { ICD10Code = "234" },
new ICD10() { ICD10Code = "345" }
};
var t2 = new List<ICD10>()
{
new ICD10() { ICD10Code = "234" },
new ICD10() { ICD10Code = "456" }
};
// returns list with just one element - the one with ICF10Code == "234"
var results = t1.Intersect(t2, new ICD10Comparer()).ToList();
// return list with 4 elements
var results2 = t1.Union(t2, new ICD10Comparer()).ToList();
使用ICD10
和ICD10Comparer
类声明。一切都很好!您必须搜索自定义代码中的错误,因为LINQ工作得很好。