代码之家  ›  专栏  ›  技术社区  ›  Andrew Florko

C#:如何检查相同大小和相同元素的列表?

  •  6
  • Andrew Florko  · 技术社区  · 14 年前

    有两个字符串列表

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

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

    6 回复  |  直到 14 年前
        1
  •  25
  •   Jon Skeet    14 年前

    如果你不需要担心重复:

    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
  •  2
  •   Community uzul    7 年前
    A.Count == B.Count && new HashSet<string>(A).SetEquals(B);
    

    如果重复出现的频率不同,请查看 this question .

        3
  •  1
  •   Andy    14 年前

    如果你打电话 Enumerable.Except() 在这两个列表中,将返回 IEnumerable<string> 包含一个列表中而不是另一个列表中的所有元素。如果计数为0,那么您知道这两个列表是相同的。

        4
  •  0
  •   Tomas Jansson    14 年前
    var result = A.Count == B.Count && A.Where(y => B.Contains(y)).Count() == A.Count;
    

    也许 吧?

        5
  •  0
  •   Tom    14 年前

    一个简单的循环怎么样?

    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;
    }
    
        6
  •  0
  •   LukeH    14 年前

    如果你不关心重复,或者你关心重复,但不过分关注性能的微观优化,那么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);
    }
    

    (注意,此方法将返回 true 如果两个序列都是 null . 如果这不是期望的行为,那么就很容易添加额外的 无效的 支票。)