Zain
Zain

Reputation: 1252

Sort Dictionary (string, int) by value

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

Answers (3)

123 456 789 0
123 456 789 0

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

p.s.w.g
p.s.w.g

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

Habib
Habib

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

Related Questions