【问题标题】:Fastest way to compare two List<CustomObject>比较两个 List<CustomObject> 的最快方法
【发布时间】:2016-12-24 03:02:01
【问题描述】:

我有两个List&lt;CustomObject&gt;,分别叫list1和list2

public class CustomObject
{
    public string foo { get; set; }
    public string bar{ get; set; }
}

目标是生成一个新列表,其中包含已在 list2 中修改/添加的所有条目。

因为这些列表可能会变得很长,所以循环遍历它们不是一种选择...

有什么想法吗?

【问题讨论】:

  • 您只需要比较对象实例,还是需要对所有属性进行深度比较?
  • 我几乎只需要比较每个列表条目的 foo 的值。我想那算作深度比较?
  • list1 是您的原始列表,而 list2 是修改后的当前列表吗?如果您真的要跟踪一个列表中随着时间的推移发生了什么变化,那是一个非常不同的问题(而且答案比比较两个列表更简单)。
  • 是的,list2 是 list1 的修改版本,我想知道发生了什么变化。以我目前对英语的理解,我称之为比较两个列表,但如果有更简单的解决方案,我会很高兴听到它:)
  • 另一种选择是根本没有两个列表,而是使用 INotifyPropertyChanged 和 ObservableCollection 之类的更改跟踪策略来记录添加或修改了哪些对象,然后稍后使用该修改列表。这基本上就是 Entity Framework 识别需要向下传播到数据库的更新的方式。

标签: c# list mono


【解决方案1】:

添加另一个答案以适应 cmets 中出现的一些其他 NFR:

  1. 可以通过哈希码识别对象
  2. 列表很大,所以性能是个问题
  3. 这个想法是将旧列表与新列表进行比较,看看是否弹出了任何新的哈希码。

您需要将对象存储在字典中:

var list = new Dictionary<string, CustomObject>();

添加它们时,提供哈希作为键:

list.Add(customObject.Hash, customObject);

扫描新的:

var difference = new List<CustomObject>();
foreach (customObject o in newList)
{
    if (oldList.ContainsKey(o.Hash)) difference.Add(o);
}
Log(String.Format("{0} new hashes found.", difference.Count));

通过使用 Dictionary,您可以利用键存储在哈希表中的方式。在哈希表中查找项目比仅进行扫描和比较之类的事情要快。我相信这将是 O(n*log(n)) 而不是 O(n^2)。

【讨论】:

    【解决方案2】:

    这是一种传统的做法:

    public class CustomObject : IComparable
    {
        public string foo { get; set; }
        public string bar{ get; set; }
        public int CompareTo(CustomObject o)
        {
             if (this.foo == o.foo && this.bar == o.bar) return 0;
    
             //We have to code for the < and > comparisons too.  Could get painful if there are a lot of properties to compare.
             if (this.Foo == o.Foo) return (this.Bar.CompareTo(o.Bar));
             return this.Foo.CompareTo(o.Foo);
        }
    }
    

    然后使用Linq.Except:

    listA.Except(listB)
    

    【讨论】:

    • 请问为什么 CompareTo 必须返回一个 int?我找到了this,但我不明白返回 -1、0 和 1 有何改变。目前,这总是会产生“无法将 bool 转换为 int 错误”
    • 糟糕忘记了这个细节。已编辑。
    • 哦,现在说得通了,完全误解了那个文档
    • 我唯一担心的是,当两个实例不相等时,您可能不想返回 1。我想如果你曾经使用过,比如.Sort(),那会做坏事。为你想出 的逻辑值得麻烦吗?
    • 我不太明白你最后一句的意思,但我正在比较一堆文件的哈希值,如果 list1 中不存在 hashxyz,则必须下载该文件
    猜你喜欢
    • 1970-01-01
    • 2013-06-18
    • 2015-07-04
    • 1970-01-01
    • 1970-01-01
    • 2016-11-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多