Test whether two IEnumerable have the same values with the same frequencies

前端 未结 4 1086
轻奢々
轻奢々 2021-01-02 01:39

I have two multisets, both IEnumerables, and I want to compare them.

string[] names1 = { \"tom\", \"dick\", \"harry\" };
string[] names2 = { \

4条回答
  •  迷失自我
    2021-01-02 02:34

    First sort as you have already done, and then use Enumerable.SequenceEqual. You can use the first overload if your type implements IEquatable or overrides Equals; otherwise you will have to use the second form and provide your own IEqualityComparer.

    So if your type does implement equality, just do:

    return a.SequenceEqual(b);
    

    Here's another option that is both faster, safer, and requires no sorting:

    public static bool UnsortedSequencesEqual(
        this IEnumerable first,
        IEnumerable second)
    {
        return UnsortedSequencesEqual(first, second, null);
    }
    
    public static bool UnsortedSequencesEqual(
        this IEnumerable first,
        IEnumerable second,
        IEqualityComparer comparer)
    {
        if (first == null)
            throw new ArgumentNullException("first");
    
        if (second == null)
            throw new ArgumentNullException("second");
    
        var counts = new Dictionary(comparer);
    
        foreach (var i in first) {
            int c;
            if (counts.TryGetValue(i, out c))
                counts[i] = c + 1;
            else
                counts[i] = 1;
        }
    
        foreach (var i in second) {
            int c;
            if (!counts.TryGetValue(i, out c))
                return false;
    
            if (c == 1)
                counts.Remove(i);
            else
                counts[i] = c - 1;
        }
    
        return counts.Count == 0;
    }
    

提交回复
热议问题