我正在处理两个包含许多属性的列表。我试图遍历列表并以count(int)的形式返回两个对象的比较。计数定义为相等的属性数。
下面是一个示例:
class Object{
public string prop1 {get;set;} //x5 Avg Length (20-30 Char)
public double prop2 {get;set;} //x3
}
private int CompareProps(Object a, Object b)
{
int matchedElements = 0;
if (a.Prop1 == b.Pro1)
matchedElements++; ;
if (a.Prop2 == b.Prop2)
matchedElements++;
// More Property Comparisons...
return matchedElements;
}
///Loops in another method with two Lists of Object, where each list.count = 300
List1 = getList1Objects();//300 Objects
List2 = getList2Objects();//300 Objects
int l1 = List1.Count;
int l2 = List2.Count;
Parallel.For(0, l1, i =>
{
for (int j = 0; j < l2; j++)
{
int k = CompareProps(List1[i], List2[j]);
}
});
这是非常低效的。在C#中有更好的方法吗?这些属性可以是字符串,双打等。
谢谢!
答案 0 :(得分:2)
如果性能真的很重要,我认为您需要Intersect,因为它使用HashSets。
private static int CompareProps(MyObject a, MyObject b)
{
var aValues = a.GetType().GetProperties().Select(x => x.GetValue(a, null));
var bValues = b.GetType().GetProperties().Select(x => x.GetValue(b, null));
return aValues.Intersect(bValues).Count();
}
这是示例用法。
var a = new MyObject
{
prop1 = "abc", // same value
prop2 = "def",
prop3 = 123,
prop4 = 456 // same value
};
var b = new MyObject
{
prop1 = "abc", // same value
prop2 = "jkl",
prop3 = 789,
prop4 = 456 // same value
};
Console.WriteLine(CompareProps(a, b)); // output 2
编辑:
通过运行300X300列表循环测试了我的解决方案。
private static void Run()
{
var alist = new List<MyObject>();
for (var i = 0; i < 300; i++)
{
alist.Add(new MyObject
{
prop1 = "abc",
prop2 = RandomString(),
prop3 = random.Next(),
prop4 = 123
});
}
var blist = new List<MyObject>();
for (var i = 0; i < 300; i++)
{
blist.Add(new MyObject
{
prop1 = "abc",
prop2 = RandomString(),
prop3 = random.Next(),
prop4 = 123
});
}
var watch = new Stopwatch();
watch.Start();
Parallel.For(0, alist.Count, i =>
{
for (var j = 0; j < blist.Count; j++)
{
Console.WriteLine("Result: " + CompareProps(alist[i], blist[j]));
}
});
Console.WriteLine(watch.Elapsed.TotalSeconds + " seconds..");
}
结果:9.1703053秒。.
答案 1 :(得分:0)
您可以像这样比较它们:
private int CompareProps(Object a, Object b)
{
int matchedElements = 0;
var props = a.GetType().GetProperties();
foreach(var prop in props)
{
var vala = prop.GetValue(a);
var valb = prop.GetValue(b);
if(vala == valb)
matchedElements++;
// More Property Comparisons...
return matchedElements;
}
为类属性的将来更改编写和维护更容易。但是请注意,这肯定会花费更多时间。因此,您打算比较不建议使用此方法的对象的数百个实例。
答案 2 :(得分:0)
如果两个列表中都可能出现相同的对象,则可以通过引用或哈希将a
与b
进行比较,以进行快速短路。
如果内部列表创建缓慢(例如,从数据库查询),则可以在大小/内存允许的情况下在循环外拍摄快照.ToList()
。
就是这样。有时候,工作就是工作。