views:

66

answers:

4

Hi I have a dictionary of type

Dictionary<DateTime,double> dictionary

How can I retrive a minimum value and key coresponding to this value from this dictionary using linq ?

+1  A: 
var min = dictionary.OrderBy(kvp => kvp.Value).First();
var minKey = min.Key;
var minValue = min.Value;

This is not very efficient though; you might want to consider MoreLinq's MinBy extension method.

If you are performing this query very often, you might want to consider a different data-structure.

Ani
This won't work if multiple keys have the same value
Jess
@Jess: Read the question: "minimum value and *key* coresponding to this value"
Ani
@Jess: Yup. He does say "key" in the singular form.
Robaticus
A: 
    Dictionary<DateTime, double> dictionary;
    //...
    double min = dictionary.Min(x => x.Value);
    var minMatchingKVPs = dictionary.Where(x => x.Value == min);

You could combine it of course if you really felt like doing it on one line, but I think the above is easier to read.

    var minMatchingKVPs = dictionary.Where(x => x.Value == dictionary.Min(y => y.Value));
Jess
The one line version has O(n^2) efficiency - it will find the minimum value in the dictionary *on every pair*.
Jon Skeet
+1  A: 

You can't easily do this efficiently in normal LINQ - you can get the minimal value easily, but finding the key requires another scan through. If you can afford that, use Jess's answer.

However, you might want to have a look at MinBy in MoreLINQ which would let you write:

var pair = dictionary.MinBy(x => x.Value);

You'd then have the pair with both the key and the value in, after just a single scan.

EDIT: As Nappy says, MinBy is also in System.Interactive in Reactive Extensions.

Jon Skeet
never saw MoreLINQ ... looks pretty neat.
Jess
`MinBy` is also part of System.Interactive.dll of the [Reactive Extensions for .NET (Rx)](http://msdn.microsoft.com/en-us/devlabs/ee794896.aspx)
Nappy
A: 

Aggregate

var minPair = dictionary.Aggregate((p1, p2) => (p1.Value < p2.Value) ? p1 : p2);

Using the mighty Aggregate method.

I know that MinBy is cleaner in this case, but with Aggregate you have more power and its built-in. ;)

Nappy