如何在VB中比较两个列表(< CustomClass>)? [英] How would I compare two Lists(Of <CustomClass>) in VB?

查看:85
本文介绍了如何在VB中比较两个列表(< CustomClass>)?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在为我的自定义类实现相等运算符=.该类具有一个属性Value,它本身就是一个List(Of OtherClass),其中OtherClass是我项目中的另一个自定义类.

I'm working on implementing the equality operator = for a custom class of mine. The class has one property, Value, which is itself a List(Of OtherClass), where OtherClass is yet another custom class in my project.

我已经实现了IComparerIComparableIEqualityComparerIEquatable接口,运算符=<>boolnot,并覆盖了EqualsGetHashCode表示OtherClass.这应该为我提供了比较这些对象所需的所有工具,并且进行了到目前为止比较这些对象的两个奇异实例的各种测试.

I've already implemented the IComparer, IComparable, IEqualityComparer, and IEquatable interfaces, the operators =, <>, bool and not, and overriden Equals and GetHashCode for OtherClass. This should give me all the tools I need to compare these objects, and various tests comparing two singular instances of these objects so far checks out.

但是,我不确定当它们位于List中时该如何处理.我不在乎列表顺序.鉴于:

However, I'm not sure how to approach this when they are in a List. I don't care about the list order. Given:

Dim x As New List(Of OtherClass) From
    {New OtherClass("foo"),
     New OtherClass("bar"),
     New OtherClass("baz")}

Dim y As New List(Of OtherClass) From
    {New OtherClass("baz"),
     New OtherClass("foo"),
     New OtherClass("bar")}

然后(x = y).ToString应该打印出True.

我需要比较此列表中相同(而非唯一)的对象集.该列表不应该支持OtherClass的重复项,但是作为例外,我将不得不弄清楚如何在以后添加它.对使用LINQ不感兴趣.看起来不错,但是在我玩过的几个示例中,这增加了性能开销,使我感到烦恼.循环很丑陋,但速度很快:)

I need to compare the same (not distinct) set of objects in this list. The list shouldn't support dupes of OtherClass, but I'll have to figure out how to add that in later as an exception. Not interested in using LINQ. It looks nice, but in the few examples I've played with, adds a performance overhead in that bugs me. Loops are ugly, but they are fast :)

一个简单的代码答案很好,但是我也想了解进行这种比较所需的逻辑.我可能将不得不多次实施上述逻辑.

A straight code answer is fine, but I'd like to understand the logic needed for such a comparison as well. I'm probably going to have to implement said logic more than a few times down the road.

推荐答案

您的示例应返回false. List<>是有序集合,如果X包含foo,bar,baz,则它与baz,foo,bar不同.您不应该改变这种预期的行为!您所描述的是套装或包,而不是清单.手提袋类似于清单,但不在乎物品的顺序.那么显然在您的示例中它将返回true.

Your example should return false. List<> is ordered collection, and if X contains foo,bar,baz, it is not the same as baz,foo,bar. You are not supposed to change this kind of expected behavior! What you describe is a set or bag, not a list. Bag is similar to list, but doesn't care about the order of items. Then it would obviously return true in your example.

为清楚起见进行列表<>按项目索引而不是其值排序.这种集合的重要属性会影响其在所有操作中的行为和速度.

Edit for clarity: List<> is ordered by indices of items, not their values. And this important property of this kind of collection affects its behavior and speed in all operations.

好吧,算了吧,假设您只是想按定义进行测试.如果对内容进行排序然后比较,最快的通用算法将是O(n * log2n).

OK, forget about it, and let's say you just want to test it as you defined. The fastest universally-applicable algorithm will be O(n*log2n) if you sort the contents and then compare.

选项:

  1. 您可以将两个列表都排序为两个临时集合,然后只需比较它们的项目即可.
  2. 您可以将X排序到一个临时集合,然后依次遍历Y,并尝试在X中找到Y的每一项并将其删除.最后,您可以看到temp是否为空,那么X和Y相同.
  3. 如果您经常比较相等性而不是经常插入新项目,则可以创建一些新的智能"列表,该列表将在插入时对项目进行排序.它由一个真实的List<>以及内部某种排序的集合组成.

复杂度的粗略分析:

选项1和2.在插入n个项目时为O(n),在比较两个列表时为O(n * log2n).

Options 1. and 2. are O(n) on insertion of n items, and O(n*log2n) on comparison of two lists.

选项3在插入n个项目时为O(n * log2n),在比较两个列表时为O(n).

Option 3. is O(n*log2n) on insertion of n items, and O(n) on comparison of two lists.

如果您想获得O(n * log2n),则可能必须转到与List<>不同的集合.如果改用HashSet类(自.NET 3.5开始),则可能会得到更快的结果.但是我还没有实践过. HashSet是无序集合(也称为集合/包)的实现.它不支持两个哈希集的比较,但是您可以通过以下方式自行完成此操作:

If you want to get under O(n*log2n), you probably have to go to a different collection than List<>. If you use class HashSet instead (present since .NET 3.5), you can probably get a much faster result. But I haven't tried it in praxis. HashSet is an implementation of unordered collection aka set/bag. It doesn't support comparison of two hashsets, but you can do this on your own this way:

使用foreach迭代X项,然后尝试在Y中查找每个项.

Use foreach to iterate thru items of X and try to find each item in Y.

if(X.Count != Y.Count) return false;
foreach(var i in X) {
  if(Y.Contains(i)==false) return false;
}
return true;

此代码在列表上非常慢,为O(n ^ 2).但是在HashSets,O(n)上应该是相当快的.如果您再也没有遇到任何隐藏的问题,那么它应该像火箭一样飞翔!

This code is very slow on lists, it's O(n^2). But it should be quite fast on HashSets, O(n). If you don't encounter any more hidden problems, this should fly like a rocket!

实际上,如果您需要使用List<>并希望HashSet<>的速度,则可以将集合中的一个(X或Y)重写为一个新类,该类将在内部包含两个集合- List<>和HashSet<>-,并将所有项目存储到它们两者中.

In praxis, if you need to stay with List<> and want the speed of HashSet<>, you can rewrite just one of your collection (either X or Y) to a new class which will contain two collections inside - a List<> and a HashSet<> - and will store all items to both of them.

您还可以使用经典的Dictionary<>,HashTable或.NET的其他一些经典集合来实现相同的功能.它们的运行速度比比较两个列表要快,但可能需要更多的内存,并且不如HashSets快.

You can also use a classic Dictionary<>, HashTable or some other classic collection of .NET to implement the same thing. They will run faster than comparing two Lists, but probably need more memory and not be as fast as HashSets.

这篇关于如何在VB中比较两个列表(&lt; CustomClass&gt;)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆