确定两个 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?

查看:39
本文介绍了确定两个 List<T> 是否存在的最佳方法是什么?对象包含相同的值集,即使它们的顺序不同?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有两个 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.
  • 计算每个值在每个集合中出现的次数,如果计数不相等则返回 false.
  • 如果我在两个集合的末尾没有任何值计数不等,则返回 true.

我知道对此有一些警告,例如 T 必须具有可比性这一事实 - 我现在使用默认比较(例如 .Equals() )并定义了适当的约束对于泛型类型.

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 反编译的)但是它不会抛出异常,而是返回一个布尔值.

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&lt;T&gt; 是否存在的最佳方法是什么?对象包含相同的值集,即使它们的顺序不同?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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