首页 > 解决方案 > 如何有效地比较两个对象并计算相等属性的数量?

问题描述

我正在使用两个包含许多属性的列表。我试图遍历列表并以计数(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# 中有没有更好的方法来做到这一点?属性可以是字符串、双精度等。

谢谢!

标签: c#list

解决方案


如果性能真的很重要,我认为您需要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 秒..

在此处输入图像描述


推荐阅读