我有一個字典與雙打值和字符串作爲關鍵。如何統計Dictionary中唯一值的出現次數?
我想統計本詞典中每個值的出現次數,我想知道這個值(例如重複)。
例如:
key1, 2
key2, 2
key3, 3
key4, 2
key5, 5
key6, 5
我希望得到一個列表:
2 - 3 (times)
3 - 1 (once)
5 - 2 (twice)
我該怎麼辦呢?
我有一個字典與雙打值和字符串作爲關鍵。如何統計Dictionary中唯一值的出現次數?
我想統計本詞典中每個值的出現次數,我想知道這個值(例如重複)。
例如:
key1, 2
key2, 2
key3, 3
key4, 2
key5, 5
key6, 5
我希望得到一個列表:
2 - 3 (times)
3 - 1 (once)
5 - 2 (twice)
我該怎麼辦呢?
首先要注意的是,你實際上並不關心字典的關鍵字。因此,第一步是忽視它們與手頭任務無關。我們將使用字典的Values
屬性,並且該工作與任何其他整數集合(或者任何其他可比較的平等類型的枚舉)的工作大致相同。
這個問題有兩種常見的方法,兩者都值得了解。
首先使用另一個字典保存值的計數:
//Start with setting up the dictionary you described.
Dictionary<string, int> dict = new Dictionary<string, int>{
{"key1", 2},
{"key2", 2},
{"key3", 3},
{"key4", 2},
{"key5", 5},
{"key6", 5}
};
//Create a different dictionary to store the counts.
Dictionary<int, int> valCount = new Dictionary<int, int>();
//Iterate through the values, setting count to 1 or incrementing current count.
foreach(int i in dict.Values)
if(valCount.ContainsKey(i))
valCount[i]++;
else
valCount[i] = 1;
//Finally some code to output this and prove it worked:
foreach(KeyValuePair<int, int> kvp in valCount)//note - not sorted, that must be added if needed
Console.WriteLine("{0} - {1}", kvp.Key, kvp.Value);
但願這是非常簡單的。另一種方法是比較複雜,但有一些長處:
//Start with setting up the dictionary you described.
Dictionary<string, int> dict = new Dictionary<string, int>{
{"key1", 2},
{"key2", 2},
{"key3", 3},
{"key4", 2},
{"key5", 5},
{"key6", 5}
};
IEnumerable<IGrouping<int, int>> grp = dict.Values.GroupBy(x => x);
//Two options now. One is to use the results directly such as with the
//equivalent code to output this and prove it worked:
foreach(IGrouping<int, int> item in grp)//note - not sorted, that must be added if needed
Console.WriteLine("{0} - {1}", item.Key, item.Count());
//Alternatively, we can put these results into another collection for later use:
Dictionary<int, int> valCount = grp.ToDictionary(g => g.Key, g => g.Count());
//Finally some code to output this and prove it worked:
foreach(KeyValuePair<int, int> kvp in valCount)//note - not sorted, that must be added if needed
Console.WriteLine("{0} - {1}", kvp.Key, kvp.Value);
(我們可能會使用var
而不是冗長IEnumerable<IGrouping<int, int>>
,但它是值得向大家解釋代碼時是準確的)。
在直截了當的比較中,這個版本更差 - 理解更復雜,效率更低。然而,學習這種方法可以爲同一技術提供一些簡潔而有效的變體,因此值得研究。
GroupBy()
接受一個枚舉並創建另一個包含鍵值對的枚舉,其中的值也是一個枚舉。 lambda x => x
意味着它是按其自身分組的,但我們對不同分組規則的靈活性不止於此。的grp
內容看起來有點像:
{
{Key=2, {2, 2, 2}}
{Key=3, {3}}
{Key=5, {5, 5}}
}
所以,如果我們遍歷這個的每一個我們拉出Key
和組呼Count()
組,我們得到我們想要的結果。
現在,在第一種情況下,我們在單個O(n)通道中構建了我們的計數,而在此我們通過O(n)通道構建該組,然後在第二個O(n )通過,使其效率低得多。這也有點難以理解,爲什麼要提起它呢?
好,第一是,一旦我們這樣做的理解,我們可以把線:
IEnumerable<IGrouping<int, int>> grp = dict.Values.GroupBy(x => x);
foreach(IGrouping<int, int> item in grp)
Console.WriteLine("{0} - {1}", item.Key, item.Count());
分爲:
foreach(var item in dict.Values.GroupBy(x => x))
Console.WriteLine("{0} - {1}", item.Key, item.Count());
這是相當簡潔,併成爲習慣。如果我們希望繼續下去,並採用值計數對做更復雜的事情,那我們就可以將其鏈接到另一個操作中,這一點尤其好。
是把結果放到一個字典版本可以更加簡潔還是:
var valCount = dict.Values.GroupBy(x => x).ToDictionary(g => g.Key, g => g.Count());
在那裏,你的整個問題在一個短線回答,而不是6(切割評論)首版。 (有些人可能更喜歡用dict.GroupBy(x => x.Value)
替換dict.Values.GroupBy(x => x)
,如果你不確定爲什麼,就試着去解決),如果你不確定爲什麼,就會得到完全相同的結果。
另一個好處是,在其他情況下,我們有更多的靈活性,GroupBy
。由於這些原因,習慣使用GroupBy
的人很可能以dict.Values.GroupBy(x => x).ToDictinary(g => g.Key, g => g.Count());
的單行簡明開始,然後轉變爲第一版本的更詳細但更有效的形式(其中我們增加了新字典中的總計數)如果它證明了性能熱點。
即使簡單的將是:
Private Function CountOccurenceOfValue(dictionary As Dictionary(Of Integer, Integer), valueToFind As Integer) As Integer
Return (From temp In dictionary Where temp.Value.Equals(valueToFind) Select temp).Count()
End Function
(是的,它是在VB.NET,但你不應該有太大的麻煩,轉換爲C#:-))
用戶正在詢問C#,因此答案應該用C#表示。 – Neeko
多一點信息:您詢問不重複的值的計數?你能給我們一個數據的例子,以及你想要的輸出嗎? – Alan
爲平等測試雙打是一個非常可疑的做法。如果你想得到答案,你可能想避免提及它。在Values屬性中使用Linq的Distinct()。Count()可以很好地匹配你的標籤。 –
你想在這裏測試雙打的平等嗎? –