什么是确定两个List< T>对象包含相同的值集,即使它们的顺序不一样吗? [英] What's the best way to determine whether two List<T> objects contain the same set of values, even if they are not in the same order?
问题描述
我有两个 List< T>
对象(其中 T
是两个对象的相同类型)我需要能够确定它们是否包含相同的值集,即使这些值的顺序不一样。
I have two List<T>
objects (where T
is the same type for both objects), and I need to be able to determine whether they contain the same set of values, even if the values aren't in the same order.
在实现这个机制,或者我需要编写自己的算法?
Do the objects have any built-in mechanisms to accomplish this, or do I need to write my own algorithm?
或者,如果我使用不同类型的集合,而不是 List< T>
?
Or perhaps, should I be using a different type of collection, rather than List<T>
?
如果我要编写自己的算法,它可能包括以下步骤 - 尝试在最终版本中优化这个,如果我走这条路线:
If I were to write my own algorithm, it would probably consist of the following steps - I'll try to optimize this in the final version, if I go this route:
- 这两个集合包含相同数量的值吗?
- 计数每个值在每个集合中显示的次数,如果计数不相等则返回false。 我到达两个集合的末尾,没有任何不相等的值计数,返回true。
- Do the two collections contain the same number of values? If not return false.
- Count the number of times each value appears in each collection, return false if the counts aren't equal.
- If I reach the end of both collections without any inequality in value counts, return true.
我知道有一些注意事项,作为事实T必须是可比的 - 我现在使用默认比较(例如 .Equals()
)与为通用类型定义的适当的约束。 p>
I know there are some caveats to this, such as the fact that T has to be comparable - I'm using the default comparison for now (e.g. .Equals()
) with appropriate constraints defined for the generic type.
推荐答案
这是重新实现 CollectionAssert.AreEquivalent
(引用代码用DotPeek反编译),但是不是抛出异常,而是返回一个bool。 p>
Here is a reimplementation of CollectionAssert.AreEquivalent
(reference code was decompiled with DotPeek) however instead of throwing a exception it returns a bool.
public class CollectionMethods
{
public static bool AreEquivalent(ICollection expected, ICollection actual)
{
//We can do a few quick tests we can do to get a easy true or easy false.
//Is one collection null and one not?
if (Object.ReferenceEquals(expected, null) != Object.ReferenceEquals(actual, null))
return false;
//Do they both point at the same object?
if (Object.ReferenceEquals(expected, actual))
return true;
//Do they have diffrent counts?
if (expected.Count != actual.Count)
return false;
//Do we have two empty collections?
if (expected.Count == 0)
return true;
//Ran out of easy tests, now have to do the slow work.
int nullCount1;
Dictionary<object, int> elementCounts1 = CollectionMethods.GetElementCounts(expected, out nullCount1);
int nullCount2;
Dictionary<object, int> elementCounts2 = CollectionMethods.GetElementCounts(actual, out nullCount2);
//One last quick check, do the two collections have the same number of null elements?
if (nullCount2 != nullCount1)
{
return false;
}
//Check for each element and see if we see them the same number of times in both collections.
foreach (KeyValuePair<object,int> kvp in elementCounts1)
{
int expectedCount = kvp.Value;
int actualCount;
elementCounts2.TryGetValue(key, out actualCount);
if (expectedCount != actualCount)
{
return false;
}
}
return true;
}
private static Dictionary<object, int> GetElementCounts(ICollection collection, out int nullCount)
{
Dictionary<object, int> dictionary = new Dictionary<object, int>();
nullCount = 0;
foreach (object key in (IEnumerable)collection)
{
if (key == null)
{
++nullCount;
}
else
{
int num;
dictionary.TryGetValue(key, out num);
++num;
dictionary[key] = num;
}
}
return dictionary;
}
}
这篇关于什么是确定两个List< T>对象包含相同的值集,即使它们的顺序不一样吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!