C# 如何有效地比较两个对象并计算相等属性的数量?
我正在处理两个包含许多属性的列表。我试图循环遍历列表,并以计数(int)的形式返回两个对象的比较。计数定义为相等的属性数 下面是一个例子:C# 如何有效地比较两个对象并计算相等属性的数量?,c#,list,C#,List,我正在处理两个包含许多属性的列表。我试图循环遍历列表,并以计数(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)
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]);
}
});
类对象{
公共字符串prop1{get;set;}//x5平均长度(20-30个字符)
公共双属性2{get;set;}//x3
}
私有int比较操作(对象a、对象b)
{
int matchedeelements=0;
如果(a.Prop1==b.Pro1)
匹配元素++;
如果(a.Prop2==b.Prop2)
匹配元素++;
//更多财产比较。。。
返回匹配元素;
}
///使用两个对象列表在另一个方法中循环,其中每个list.count=300
List1=getList1Objects()//300件物品
List2=getList2Objects()//300件物品
int l1=List1.Count;
int l2=List2.Count;
对于(0,l1,i=>
{
对于(int j=0;j
但这是非常低效的。在C#中有更好的方法吗?属性可以是字符串、双精度等
谢谢 您可以这样比较它们:
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;
}
它更易于编写和维护,以便将来更改类属性。但要注意,这肯定需要更多的时间。因此,如果您打算比较数百个对象的实例,则不建议使用此方法。如果两个列表中可能出现相同的对象,您可以通过引用或哈希将
a
与b
进行比较,以便快速短路
如果内部列表创建速度较慢(例如,来自DB的查询),如果大小/内存允许,您可以在循环外部拍摄快照.ToList()
不过就是这样。有时候,工作就是工作。如果性能真的很重要,我认为您需要,因为它使用哈希集
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..");
}
private static void Run()
{
var alist=新列表();
对于(变量i=0;i<300;i++)
{
列表添加(新的MyObject)
{
prop1=“abc”,
prop2=RandomString(),
prop3=random.Next(),
prop4=123
});
}
var blist=新列表();
对于(变量i=0;i<300;i++)
{
blist.Add(新的MyObject
{
prop1=“abc”,
prop2=RandomString(),
prop3=random.Next(),
prop4=123
});
}
var watch=新秒表();
watch.Start();
Parallel.For(0,alist.Count,i=>
{
对于(var j=0;j
结果:9.1703053秒
它是O(1),所以一点效率都没有。不过写下来很麻烦;)您是否比较了属性类型或属性值?要比较多少属性?是否可以编辑帖子并显示对象的示例?你应该发布你的循环。OP已经指出他的设计效率低下,并且正在寻找比他2分钟解决方案更好的方法。他的意思是写得更快而不是更少的代码。2分钟的解决方案不一定是坏的。他在哪里提到更快?就像7分钟的腹肌,人们指的是6分钟的VHS版本。这是暗示。“这是非常低效的。在C#中是否有更好的方法来实现这一点?…出于某种原因,在300X300列表循环中运行这一过程大约需要2分钟。如果我将它们转换为散列或其他方式,比较起来会更快。我认为字符串比较正在扼杀这一点。”。该部分是对Adrian评论的回应。如果大多数对象不同,那么它不会提供太多好处