17

I have a dictionary in C#:

public Dictionary<Product, int>

And I would like to get my result in to a generic list:

List<Product> productList = new List<Product>();

With the products orderder descending by the int value in the dictionary. I've tried using the orderby method, but without success.

Cœur
  • 37,241
  • 25
  • 195
  • 267
Johan
  • 283
  • 1
  • 2
  • 6
  • When you say without success, are you getting a runtime exception? Or is it that the result is not sorted the way you would expect? What ordering code are you currently trying, in case the answers provided already match what you've done. – Yuck May 10 '11 at 12:25
  • I used orderby() on the values, but didnt know that i could fetch the key values with select(). So problem solved :) – Johan May 10 '11 at 12:42
  • 4
    Maybe you should consider using a `SortedDictionary` – Magnus May 10 '11 at 12:46

4 Answers4

30

You can do that using:

List<Product> productList = dictionary.OrderByDescending(kp => kp.Value)
                                      .Select(kp => kp.Key)
                                      .ToList();
driis
  • 161,458
  • 45
  • 265
  • 341
  • Thanks, all of you. Followup question: Do i use the Take-method to get x number of results? If i want a limit – Johan May 10 '11 at 12:25
  • Yes, you can use .Take(x) to get x results. (And Skip() if you are trying to do paging. Remember the order of these operators matter). – driis May 10 '11 at 12:28
  • Yes, You can use Take(int n) to limit your select – Stecya May 10 '11 at 12:28
  • @Johan. Yes Take(6) will return the first six results. You can also use Skip(). E.g. Skip(6).Take(4) will skips the first 6 results and return the next 4. – Ben Robinson May 10 '11 at 12:28
6

Try this

List<Product> productList = dictionary.OrderByDescending(x => x.Value).Select(x => x.Key).ToList();
Stecya
  • 22,896
  • 10
  • 72
  • 102
5
MyDict.OrderByDescending(x => x.Value).Select(p => p.Key).ToList();
Ben Robinson
  • 21,601
  • 5
  • 62
  • 79
5

Here's an example using LINQ query syntax.

 public class TestDictionary 
    {
        public void Test()
        {
            Dictionary<Product, int> dict=new Dictionary<Product, int>();
            dict.Add(new Product(){Data = 1}, 1);
            dict.Add(new Product() { Data = 2 }, 2);
            dict.Add(new Product() { Data = 3 }, 3);
            dict.Add(new Product() { Data = 4 }, 9);
            dict.Add(new Product() { Data = 5 }, 5);
            dict.Add(new Product() { Data = 6 }, 6);

            var query=(from c in dict 
                orderby c.Value descending 
                select c.Key).ToList();       
        }
        [DebuggerDisplay("{Data}")]
        public class Product
        {
            public int Data { get; set; }
        }           
    }
p.campbell
  • 98,673
  • 67
  • 256
  • 322
crypted
  • 10,118
  • 3
  • 39
  • 52
  • 1
    "pure Linq" is a very controversal statement, because your query will be compiled to the method chain above. Even more "pure" would be to write IEnumerable method chains with delegates. – Nappy May 10 '11 at 12:59