How do you sort a dictionary by value?

前端 未结 19 2370
误落风尘
误落风尘 2020-11-22 03:51

I often have to sort a dictionary, consisting of keys & values, by value. For example, I have a hash of words and respective frequencies, that I want to order by frequen

相关标签:
19条回答
  • 2020-11-22 04:07

    Required namespace : using System.Linq;

    Dictionary<string, int> counts = new Dictionary<string, int>();
    counts.Add("one", 1);
    counts.Add("four", 4);
    counts.Add("two", 2);
    counts.Add("three", 3);
    

    Order by desc :

    foreach (KeyValuePair<string, int> kvp in counts.OrderByDescending(key => key.Value))
    {
    // some processing logic for each item if you want.
    }
    

    Order by Asc :

    foreach (KeyValuePair<string, int> kvp in counts.OrderBy(key => key.Value))
    {
    // some processing logic for each item if you want.
    }
    
    0 讨论(0)
  • 2020-11-22 04:08

    The other answers are good, if all you want is to have a "temporary" list sorted by Value. However, if you want to have a dictionary sorted by Key that automatically synchronizes with another dictionary that is sorted by Value, you could use the Bijection<K1, K2> class.

    Bijection<K1, K2> allows you to initialize the collection with two existing dictionaries, so if you want one of them to be unsorted, and you want the other one to be sorted, you could create your bijection with code like

    var dict = new Bijection<Key, Value>(new Dictionary<Key,Value>(), 
                                   new SortedDictionary<Value,Key>());
    

    You can use dict like any normal dictionary (it implements IDictionary<K, V>), and then call dict.Inverse to get the "inverse" dictionary which is sorted by Value.

    Bijection<K1, K2> is part of Loyc.Collections.dll, but if you want, you could simply copy the source code into your own project.

    Note: In case there are multiple keys with the same value, you can't use Bijection, but you could manually synchronize between an ordinary Dictionary<Key,Value> and a BMultiMap<Value,Key>.

    0 讨论(0)
  • 2020-11-22 04:13

    Actually in C#, dictionaries don't have sort() methods. As you are more interested in sort by values, you can't get values until you provide them key. In short, you need to iterate through them using LINQ's OrderBy(),

    var items = new Dictionary<string, int>();
    items.Add("cat", 0);
    items.Add("dog", 20);
    items.Add("bear", 100);
    items.Add("lion", 50);
    
    // Call OrderBy() method here on each item and provide them the IDs.
    foreach (var item in items.OrderBy(k => k.Key))
    {
        Console.WriteLine(item);// items are in sorted order
    }
    

    You can do one trick:

    var sortedDictByOrder = items.OrderBy(v => v.Value);
    

    or:

    var sortedKeys = from pair in dictName
                orderby pair.Value ascending
                select pair;
    

    It also depends on what kind of values you are storing: single (like string, int) or multiple (like List, Array, user defined class). If it's single you can make list of it and then apply sort.
    If it's user defined class, then that class must implement IComparable, ClassName: IComparable<ClassName> and override compareTo(ClassName c) as they are more faster and more object oriented than LINQ.

    0 讨论(0)
  • 2020-11-22 04:18

    Given you have a dictionary you can sort them directly on values using below one liner:

    var x = (from c in dict orderby c.Value.Order ascending select c).ToDictionary(c => c.Key, c=>c.Value);
    
    0 讨论(0)
  • 2020-11-22 04:20

    On a high level, you have no other choice than to walk through the whole Dictionary and look at each value.

    Maybe this helps: http://bytes.com/forum/thread563638.html Copy/Pasting from John Timney:

    Dictionary<string, string> s = new Dictionary<string, string>();
    s.Add("1", "a Item");
    s.Add("2", "c Item");
    s.Add("3", "b Item");
    
    List<KeyValuePair<string, string>> myList = new List<KeyValuePair<string, string>>(s);
    myList.Sort(
        delegate(KeyValuePair<string, string> firstPair,
        KeyValuePair<string, string> nextPair)
        {
            return firstPair.Value.CompareTo(nextPair.Value);
        }
    );
    
    0 讨论(0)
  • 2020-11-22 04:21

    Looking around, and using some C# 3.0 features we can do this:

    foreach (KeyValuePair<string,int> item in keywordCounts.OrderBy(key=> key.Value))
    { 
        // do something with item.Key and item.Value
    }
    

    This is the cleanest way I've seen and is similar to the Ruby way of handling hashes.

    0 讨论(0)
提交回复
热议问题