簡體   English   中英

如何檢查字典中的所有值在C#中是否相同?

[英]How to Check All Values in Dictionary is same in C#?

我有一個字典,我想寫一個方法來檢查這個字典中的所有值是否相同。 字典類型:

Dictionary<string, List<string>>

在我的案例中,列表{1,2,3}和{2,1,3}是相同的。

我之前已經為簡單的數據類型值做了這個,但我找不到新要求的邏輯,請幫助我。 對於簡單值:MyDict.GroupBy(x => x.Value).Where(x => x.Count()> 1)

我還編寫了一個通用方法來以這種方式比較兩種數據類型。

// 1
            // Require that the counts are equal
            if (a.Count != b.Count)
            {
                return false;
            }
            // 2
            // Initialize new Dictionary of the type
            Dictionary<T, int> d = new Dictionary<T, int>();
            // 3
            // Add each key's frequency from collection A to the Dictionary
            foreach (T item in a)
            {
                int c;
                if (d.TryGetValue(item, out c))
                {
                    d[item] = c + 1;
                }
                else
                {
                    d.Add(item, 1);
                }
            }
            // 4
            // Add each key's frequency from collection B to the Dictionary
            // Return early if we detect a mismatch
            foreach (T item in b)
            {
                int c;
                if (d.TryGetValue(item, out c))
                {
                    if (c == 0)
                    {
                        return false;
                    }
                    else
                    {
                        d[item] = c - 1;
                    }
                }
                else
                {
                    // Not in dictionary
                    return false;
                }
            }
            // 5
            // Verify that all frequencies are zero
            foreach (int v in d.Values)
            {
                if (v != 0)
                {
                    return false;
                }
            }
            // 6
            // We know the collections are equal
            return true;

List<string>實現IEqualityComparer ,根據其內容比較兩個列表。 然后只需使用Distinct on Values並檢查計數:

dictionary.Values.Distinct(new ListEqualityComparer()).Count() == 1

這應該可以解決問題

var lists = dic.Select(kv => kv.Value.OrderBy(x => x)).ToList();
var first = lists.First();
var areEqual = lists.Skip(1).All(hs => hs.SequenceEqual(first));

您需要添加一些檢查才能使其適用於空案例。

...或者如果你想采用@Selman的方法,這里是IEqualityComparer的一個實現:

class SequenceComparer<T>:IEqualityComparer<IEnumerable<T>>
{
    public bool Equals(IEnumerable<T> left, IEnumerable<T> right)
    {
        return left.OrderBy(x => x).SequenceEqual(right.OrderBy(x => x));
    }
    public int GetHashCode(IEnumerable<T> item)
    {
        //no need to sort because XOR is commutative
        return item.Aggregate(0, (acc, val) => val.GetHashCode() ^ acc);
    }
}

您可以使用HashSet<T>組合這兩種方法中的最佳方法,在您有許多候選測試的情況下可能會更有效:

HashSet<IEnumerable<int>> hs = new HashSet<IEnumerable<int>>(new SequenceComparer<int>());
hs.Add(dic.First().Value);
var allEqual = dic.All(kvp => !hs.Add(kvp.Value));

這使用HashSets的功能,該功能不允許添加多個與該集合中已有項目相同的項目。 我們讓HashSet使用上面的自定義IEqualityComparer ...

所以我們在開始之前從字典中插入一個任意項目,然后當另一個項目被允許進入集合時(即hs.Add(kvp.Value)true ),我們可以說集合中有多個項目,早點救助。 .All這一切都是自動完成的。

Selman22的答案非常有效 - 您也可以為Dictionary<string, List<string>>執行此操作,而無需自己實現IEqualityComparer

var firstValue = dictionary.Values.First().OrderBy(x => x);
return dictionary.Values.All (x => x.OrderBy(y => y).SequenceEqual(firstValue));

我們將第一個值與每個其他值進行比較,並在每種情況下檢查相等性。 請注意, List<string>.OrderBy(x => x)只是按字母順序對字符串列表進行排序。

它不是最快的解決方案,但它適用於我:

bool AreEqual = l1.Intersect(l2).ToList().Count() == l1.Count() && l1.Count() == l2.Count();

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM