我正在尝试使用linq在一组属性中查找自定义对象列表中的最佳匹配项。在下面创建的MyObjects列表中,我想找到最接近testObject的对象,跨越MyObject的四个属性:
IList<MyObject> list = new List<MyObject>();
list.Add(new MyObject { Property1 = "A", Property2 = "B", Property3 = "C", Property4 = "D" });
list.Add(new MyObject { Property1 = "A", Property2 = "A", Property3 = "C", Property4 = "D" });
list.Add(new MyObject { Property1 = "A", Property2 = "A", Property3 = "A", Property4 = "D" });
var testObject = new MyObject { Property1 = "A", Property2 = "A", Property3 = "A", Property4 = "A" };
在上面的例子中,我希望匹配最后一个对象,其中3个或4个属性与testObject中的属性匹配。
我可以通过这样做来确定有多少个属性匹配:
var matchCount = list.Max(x => (x.Property1 == testObject.Property1 ? 1 : 0) +
(x.Property2 == testObject.Property2 ? 1 : 0) +
(x.Property3 == testObject.Property3 ? 1 : 0) +
(x.Property4 == testObject.Property4 ? 1 : 0));
但我无法想到如何挑选出除了写出一个非常长的Linq表达式检查每个属性组合的3个匹配项之外,符合三个属性条件的实体。理想情况下,我希望有一种解决方案,适用于具有10个属性的对象。
有人知道是否有一种被认可的方法来做到这一点吗?
编辑
我错过了原问题中的一个额外信息......如果有多个对象匹配,则需要选择与该准确度相匹配的对象列表(即,如果有一个对象在3个属性上匹配,则我需要找到所有在3个属性上匹配的对象)
解决方案
根据Sloth的答案,我已经能够通过以下方式获得想要的结果。不过,如果有人有更好的答案,我很感兴趣...
var grouping = list.GroupBy(x => (x.Property1 == testObject.Property1 ? 1 : 0) +
(x.Property2 == testObject.Property2 ? 1 : 0) +
(x.Property3 == testObject.Property3 ? 1 : 0) +
(x.Property4 == testObject.Property4 ? 1 : 0));
var maxCount = grouping.Max(x => x.Key);
var resultSet = grouping.FirstOrDefault(x => x.Key == maxCount).Select(g => g).ToList();
OrderBy
替换为GroupBy
,然后再进行排序。 - undefined