2016-12-24 39 views
0

我有两个List<CustomObject>,称为列表1和List2最快的方式比较两个List <CustomObject>

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

的目标是产生与list2中添加已修改的所有条目/一个新的列表。

因为这些名单会很长,通过这些循环是不是一个选项...

任何想法?

+0

你只需要比较对象实例,或者你需要执行一个比较深的所有属性? –

+0

我几乎只需要比较每个列表条目的foo的值。我想这算是深刻的比较呢? – CiriousJoker

+0

是list1你的原始列表和list2是修改后的当前列表?如果你真的想要跟踪一个列表中随着时间的推移发生了什么变化,这是一个非常不同的问题(并且比回答两个列表的答案要简单)。 – PMV

回答

1

添加另一种答案,以适应已经拿出在评论一些额外的NFRs的:

  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)); 

通过使用字典,你走T方式的优点他的密钥存储在一个哈希表中。在散列表中查找项目比仅仅执行扫描更快速。我相信这将是O(n * log(n))而不是O(n^2)。

1

这里有一个传统的方式做到这一点:

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) 
+0

请问为什么CompareTo必须返回一个int?我发现[this](https://msdn.microsoft.com/en-us/library/system.icomparable.compareto(v = vs.110).aspx),但我不明白如何返回-1,0 1改变任何东西。目前,这总是会产生一个“不能将bool转换为int错误” – CiriousJoker

+0

糟糕的是,忘记了这个细节。编辑。 –

+0

哦,现在它是有道理的,完全误解了文档 – CiriousJoker