Reputation: 1252
So basically I'm having an issue with the task I've been given. I won't bore you with the details of the task itself so I'll just give you the relevant info.
I have a dictionary that I need to be sorted by the int[value] that is the highest, well the top five highest to be precise and I need to be able to show the bottom five as well.
Dictionary<string, int> dict = new Dictionary<string, int>();
The strings(keys) hold words that have been read for a text file. The ints (values) hold ints of how many times they were mentioned in the document.
I was going to do it in another way but I was told to do it with a dictionary so please dictionary only help. I would appreciate it if you can explain how it should be done so I can learn as well as complete the task as the aim of the task is to educate myself but I'm finding it a bit hard..
I appreciate all your help in advance, if more info is required please let me know and I'll post it!
Upvotes: 14
Views: 39569
Reputation: 10865
If you are using C# 3.0 and higher
You can do something like this with LINQ
foreach (KeyValuePair<string,int> item in keywordCounts.OrderBy(key=> key.Value).Take(5))
{
// do something with item.Key and item.Value
}
If you are using C# 2.0
List<KeyValuePair<string, string>> myList = aDictionary.ToList();
myList.Sort((firstPair,nextPair) =>
{
return firstPair.Value.CompareTo(nextPair.Value);
}
);
or it can be rewritten as
myList.Sort((x,y)=>x.Value.CompareTo(y.Value));
LINQ
allows for great flexibility in that you can select the top 10, 20 10% etc. Or if you are using your word frequency index for type-ahead, you could also include StartsWith clause as well.
Upvotes: 3
Reputation: 149020
Dictionaries do not have any inherent order. But if you want to get the top 5 entries with highest (or lowest) values, you can use a little Linq:
using System.Linq;
...
var top5 = dict.OrderByDescending(pair => pair.Value).Take(5);
var bottom5 = dict.OrderBy(pair => pair.Value).Take(5);
This will return an IEnumerable<KeyValuePair<string, int>>
. To turn it back into a dictionary, again Linq can help. For example:
var top5 = dict.OrderByDescending(pair => pair.Value).Take(5)
.ToDictionary(pair => pair.Key, pair => pair.Value);
Now, top5
is a Dictionary<string, int>
which contains only the 5 elements from dict
with the hightest value.
Upvotes: 35
Reputation: 223277
You need to get ordered result from your dictionary, Since you are looking for Top 5, you will need Take
like:
//Top 5
foreach (var item in dict.OrderByDescending(r => r.Value).Take(5))
{
Console.WriteLine("Key: {0}, Value: {1}", item.Key, item.Value);
}
The reason you need an OrderBy is because:
Dictionary<TKey, TValue> Class
For purposes of enumeration, each item in the dictionary is treated as a KeyValuePair structure representing a value and its key. The order in which the items are returned is undefined.
Upvotes: 4