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

时间:2010-11-24 12:03:39

标签: c# .net linq algorithm

有两个字符串列表

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

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

6 个答案:

答案 0 :(得分:25)

如果您不需要担心重复:

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);

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

答案 1 :(得分:2)

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

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

答案 2 :(得分:1)

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

答案 3 :(得分:0)

如果您不关心重复,或者您担心重复但不过分关注性能微观优化,那么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。如果这不是所需的行为,那么添加额外的null检查就足够了。)

答案 4 :(得分:0)

var result = A.Count == B.Count && A.Where(y => B.Contains(y)).Count() == A.Count;

也许?

答案 5 :(得分:0)

一个简单的循环怎么样?

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;
}