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

查看:81
本文介绍了什么是确定两个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。
  • 我到达两个集合的末尾,没有任何不相等的值计数,返回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&lt; T&gt;对象包含相同的值集,即使它们的顺序不一样吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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