我有两个List<CustomObject>
,称为列表1和List2最快的方式比较两个List <CustomObject>
public class CustomObject
{
public string foo { get; set; }
public string bar{ get; set; }
}
的目标是产生与list2中添加已修改的所有条目/一个新的列表。
因为这些名单会很长,通过这些循环是不是一个选项...
任何想法?
我有两个List<CustomObject>
,称为列表1和List2最快的方式比较两个List <CustomObject>
public class CustomObject
{
public string foo { get; set; }
public string bar{ get; set; }
}
的目标是产生与list2中添加已修改的所有条目/一个新的列表。
因为这些名单会很长,通过这些循环是不是一个选项...
任何想法?
添加另一种答案,以适应已经拿出在评论一些额外的NFRs的:
你会想你的对象存储在词典:
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)。
这里有一个传统的方式做到这一点:
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](https://msdn.microsoft.com/en-us/library/system.icomparable.compareto(v = vs.110).aspx),但我不明白如何返回-1,0 1改变任何东西。目前,这总是会产生一个“不能将bool转换为int错误” – CiriousJoker
糟糕的是,忘记了这个细节。编辑。 –
哦,现在它是有道理的,完全误解了文档 – CiriousJoker
你只需要比较对象实例,或者你需要执行一个比较深的所有属性? –
我几乎只需要比较每个列表条目的foo的值。我想这算是深刻的比较呢? – CiriousJoker
是list1你的原始列表和list2是修改后的当前列表?如果你真的想要跟踪一个列表中随着时间的推移发生了什么变化,这是一个非常不同的问题(并且比回答两个列表的答案要简单)。 – PMV