比较两个列表的差异
我想要一些关于如何最好地编写一个通用函数来比较两个列表的反馈。 列表包含类对象,我们希望迭代一个列表,在第二个列表中查找相同的项目并报告任何差异。
我们已经有一个比较类的方法,因此我们需要有关如何从两个列表提供该方法(如下所示)的反馈。
例如,假设我们有一个简单的“Employee”类,它具有三个属性:Name、ID、Department。 我们想要报告 List 和另一个 List 之间的差异。
注:
两个列表将始终包含相同数量的项目。
如上所述,我们有一个用于比较两个类的通用方法,我们如何合并该方法来满足列表,即从另一个方法,循环遍历列表并将类提供给通用方法....但是我们如何在第二个列表中找到等效的类以传递给下面的方法;
public static string CompareTwoClass_ReturnDifferences<T1, T2>(T1 Orig, T2 Dest)
where T1 : class
where T2 : class
{
// Instantiate if necessary
if (Dest == null) throw new ArgumentNullException("Dest", "Destination class must first be instantiated.");
var Differences = CoreFormat.StringNoCharacters;
// Loop through each property in the destination
foreach (var DestProp in Dest.GetType().GetProperties())
{
// Find the matching property in the Orig class and compare
foreach (var OrigProp in Orig.GetType().GetProperties())
{
if (OrigProp.Name != DestProp.Name || OrigProp.PropertyType != DestProp.PropertyType) continue;
if (OrigProp.GetValue(Orig, null).ToString() != DestProp.GetValue(Dest, null).ToString())
Differences = Differences == CoreFormat.StringNoCharacters
? string.Format("{0}: {1} -> {2}", OrigProp.Name,
OrigProp.GetValue(Orig, null),
DestProp.GetValue(Dest, null))
: string.Format("{0} {1}{2}: {3} -> {4}", Differences,
Environment.NewLine,
OrigProp.Name,
OrigProp.GetValue(Orig, null),
DestProp.GetValue(Dest, null));
}
}
return Differences;
}
有什么建议或想法值得赞赏吗?
编辑:针对 .NET 2.0,因此 LINQ 是不可能的。
I would like some feedback on how we can best write a generic function that will enable two Lists to be compared. The Lists contain class objects and we would like to iterate through one list, looking for the same item in a second List and report any differences.
We already have a method to compare classes, so we need feedback on how we can feed the method (shown below) from two Lists.
For example, say we have a simple "Employee" class that has three properties, Name, ID, Department. We want to report the differences between List and another List.
Note:
Both lists will always contain the same number of items.
As mentioned above, we have a generic method that we use to compare two classes, how can we incorporate this method to cater for Lists, i.e. from another method, loop through the List and feed the classes to the generic method .... but how do we find the equivalent class in the second List to pass to the method below;
public static string CompareTwoClass_ReturnDifferences<T1, T2>(T1 Orig, T2 Dest)
where T1 : class
where T2 : class
{
// Instantiate if necessary
if (Dest == null) throw new ArgumentNullException("Dest", "Destination class must first be instantiated.");
var Differences = CoreFormat.StringNoCharacters;
// Loop through each property in the destination
foreach (var DestProp in Dest.GetType().GetProperties())
{
// Find the matching property in the Orig class and compare
foreach (var OrigProp in Orig.GetType().GetProperties())
{
if (OrigProp.Name != DestProp.Name || OrigProp.PropertyType != DestProp.PropertyType) continue;
if (OrigProp.GetValue(Orig, null).ToString() != DestProp.GetValue(Dest, null).ToString())
Differences = Differences == CoreFormat.StringNoCharacters
? string.Format("{0}: {1} -> {2}", OrigProp.Name,
OrigProp.GetValue(Orig, null),
DestProp.GetValue(Dest, null))
: string.Format("{0} {1}{2}: {3} -> {4}", Differences,
Environment.NewLine,
OrigProp.Name,
OrigProp.GetValue(Orig, null),
DestProp.GetValue(Dest, null));
}
}
return Differences;
}
Any suggestions or ideas appreciated?
Edit: Targeting .NET 2.0 so LINQ is out of the question.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
该解决方案生成一个结果列表,其中包含两个输入列表的所有差异。
您可以通过任何属性来比较对象,在我的示例中它是 ID。
唯一的限制是列表应该是同一类型:
This solution produces a result list, that contains all differences from both input lists.
You can compare your objects by any property, in my example it is ID.
The only restriction is that the lists should be of the same type:
这是你的实际问题; 你必须至少有一个不可变的属性,一个 id 或类似的东西,来识别两个列表中相应的对象。 如果您没有这样的属性,则无法无错误地解决问题。 您可以尝试通过搜索最小或逻辑变化来猜测相应的对象。
如果你有这样的属性,那么解决方案就变得非常简单。
现在我很困惑......这有什么问题吗? 为什么不只是以下内容?
如果保证长度相等,甚至可以省略 Math.Min() 调用。
由于委托和使用枚举器而不是使用 ICollection,Noldorin 的实现当然更加智能。
This is your actual problem; you must have at least one immutable property, a id or something like that, to identify corresponding objects in both lists. If you do not have such a property you, cannot solve the problem without errors. You can just try to guess corresponding objects by searching for minimal or logical changes.
If you have such an property, the solution becomes really simple.
Now I am confused ... what is the problem with that? Why not just the following?
The Math.Min() call may even be left out if equal length is guaranted.
Noldorin's implementation is of course smarter because of the delegate and the use of enumerators instead of using ICollection.
我认为您正在寻找这样的方法:
它未经测试,但它应该可以完成工作。 请注意,此方法特别有用的是它是完全通用的,即它可以采用两个任意(和不同)类型的序列并返回任何类型的对象。
当然,此解决方案假设您想要将
seq1
的第 n 项与seq2
中的第 n 项进行比较。 如果您想根据特定属性/比较来匹配两个序列中的元素,那么您将需要执行某种 join 操作(如 danbruc 使用Enumerable.Join
建议的那样。如果这两种方法都不完全是我想要的,请告诉我我正在寻找,也许我可以提出其他建议编辑: 。
以下示例展示了如何将
CompareSequences
方法与您最初发布的比较器函数结合使用。I think you're looking for a method like this:
It's untested, but it should do the job nonetheless. Note that what's particularly useful about this method is that it's full generic, i.e. it can take two sequences of arbitrary (and different) types and return objects of any type.
This solution of course assumes that you want to compare the nth item of
seq1
with the nth item inseq2
. If you want to do match the elements in the two sequences based on a particular property/comparison, then you'll want to perform some sort of join operation (as suggested by danbruc usingEnumerable.Join
. Do let me know if it neither of these approaches is quite what I'm after and maybe I can suggest something else.Edit:
Here's an example of how you might use the
CompareSequences
method with the comparer function you originally posted.Microsoft 的这种方法非常有效,它提供了将一个列表与另一个列表进行比较并切换它们以获得每个列表之间差异的选项。 如果您要比较类,只需将对象添加到两个单独的列表中,然后运行比较即可。
http://msdn.microsoft.com/en-us/library/bb397894.aspx
This approach from Microsoft works very well and provides the option to compare one list to another and switch them to get the difference in each. If you are comparing classes simply add your objects to two separate lists and then run the comparison.
http://msdn.microsoft.com/en-us/library/bb397894.aspx
我希望我正确理解了您的问题,但是您可以使用 Linq 快速完成此操作。 我假设您通常都会有一个 Id 属性。 只需创建一个接口即可确保这一点。
如果您如何识别相同的对象因类而异,我建议传入一个委托,如果两个对象具有相同的持久 ID,则该委托返回 true。
在 Linq 中执行此操作的方法如下:
I hope that I am understing your question correctly, but you can do this very quickly with Linq. I'm assuming that universally you will always have an Id property. Just create an interface to ensure this.
If how you identify an object to be the same changes from class to class, I would recommend passing in a delegate that returns true if the two objects have the same persistent id.
Here is how to do it in Linq: