【问题标题】:C#: how do you check lists are the same size & same elements?C#:如何检查列表的大小和元素是否相同?
【发布时间】:2010-11-24 12:03:38
【问题描述】:

有两个字符串列表

List<string> A;
List<string> B;

您建议检查 A.Count == B.Count 以及 B 中 A 的每个元素(反之亦然)的最短代码是什么:每个 B 都在 A 中(A 项目和 B 项目可能有不同的顺序)。

【问题讨论】:

    标签: c# .net linq algorithm


    【解决方案1】:

    如果您不需要担心重复:

    bool equal = new HashSet<string>(A).SetEquals(B);
    

    如果您担心重复,那就有点尴尬了。这会起作用,但速度相对较慢:

    bool equal = A.OrderBy(x => x).SequenceEquals(B.OrderBy(x => x));
    

    当然,您可以通过首先检查计数来提高这两个选项的效率,这是一个简单的表达式。例如:

    bool equal = (A.Count == B.Count) && new HashSet<string>(A).SetEquals(B);
    

    ...但您要求最短的代码:)

    【讨论】:

      【解决方案2】:
      A.Count == B.Count && new HashSet<string>(A).SetEquals(B);
      

      如果不同频率的重复是个问题,请查看this question

      【讨论】:

        【解决方案3】:

        如果您在两个列表上调用Enumerable.Except(),则将返回一个IEnumerable&lt;string&gt;,其中包含一个列表中但不包含另一个列表中的所有元素。如果 this 的计数为 0,那么你知道这两个列表是相同的。

        【讨论】:

        • Enumerable.Distinct()one 序列上运行。你的意思是Enumerable.Except()
        • @Jon 啊,是的,我做到了,感谢您的澄清。我会更新我的答案。
        【解决方案4】:
        var result = A.Count == B.Count && A.Where(y => B.Contains(y)).Count() == A.Count;
        

        也许?

        【讨论】:

        • 谢谢,我制作了类似的东西,但@Jon Skeet 提供了出色的代码:)
        【解决方案5】:

        一个简单的循环怎么样?

        private bool IsEqualLists(List<string> A, List<string> B)
        {
            for(int i = 0; i < A.Count; i++)
            {
                if(i < B.Count - 1) {
                    return false; }
                else 
                {
                    if(!String.Equals(A[i], B[i]) {
                        return false;
                    }
                }
            }
            return true;
        }
        

        【讨论】:

        • 我更喜欢基于 groovy linq 的方式,比如下面的答案 A.SequenceEqual 很棒。
        • 这假定两个列表的顺序相同 - 它们可能不是,即使它们当时是 SequenceEqual,正如你所说,很多更优雅.
        • 啊,是的,我实际上误读了关于不同顺序是可接受这一事实的问题。好的非 linq 路线应该是 A.TrueForAll(a => B.Contains(a));
        【解决方案6】:

        如果您不关心重复,或者您关心重复但不太关心性能微优化,那么 Jon 回答中的各种技术绝对是要走的路。

        如果您担心重复性能,那么类似这种扩展方法应该可以解决问题,尽管它确实不符合您的“最短代码”标准!

        bool hasSameElements = A.HasSameElements(B);
        
        // ...
        
        public static bool HasSameElements<T>(this IList<T> a, IList<T> b)
        {
            if (a == b) return true;
        
            if ((a == null) || (b == null)) return false;
        
            if (a.Count != b.Count) return false;
        
            var dict = new Dictionary<string, int>(a.Count);
            foreach (string s in a)
            {
                int count;
                dict.TryGetValue(s, out count);
                dict[s] = count + 1;
            }
        
            foreach (string s in b)
            {
                int count;
                dict.TryGetValue(s, out count);
        
                if (count < 1) return false;
        
                dict[s] = count - 1;
            }
        
            return dict.All(kvp => kvp.Value == 0);
        }
        

        (请注意,如果两个序列都是null,此方法将返回true。如果这不是所需的行为,那么添加额外的null 检查很容易。)

        【讨论】:

          猜你喜欢
          • 2012-08-22
          • 1970-01-01
          • 2011-09-01
          • 2022-01-06
          • 2011-04-20
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多