Abanoub
Abanoub

Reputation: 3809

select the min value using linq

I have a Dictionary

Dictionary<Location2D, int> h_scores = new Dictionary<Location2D, int>();

and I want to select the Key // which is Location2D by the minimum int value.

I tried

h_scores.Min().Key; // not working
h_scores.OrderBy(x => x.Value).Select(y=> y.Key).Min(); //error At least one object must implement IComparable.

so how can I select a key by the smallest int value?

Upvotes: 4

Views: 7556

Answers (4)

Igor Korkhov
Igor Korkhov

Reputation: 8558

Just for the sake of diversity, the solution which doesn't need external dependencies (e.g. MoreLinq) and is O(n) in contrast to OrderBy() solutions which are at least O(n*log(n)):

var minKey =
    h_scores.Aggregate(h_scores.First(), (min, curr) => curr.Value < min.Value ? curr : min).Key;

Upvotes: 3

Justin Niessner
Justin Niessner

Reputation: 245399

You just need to use the right overload of Min:

val minKey = h_scores.Min(s => s.Value).Key;

Update

Didn't pay attention to the return value of the overload for Min. You are definitely looking for MinBy from Jon Skeet's morelinq:

val minKey = h_scores.MinBy(s => s.Value).Key;

Upvotes: 7

David Peden
David Peden

Reputation: 18424

I don't know what a Location2D is but you can use the following example to do what you want. Just sub in your class instead of string. Also, because values are not guaranteed to be unique in a Dictionary (but may be in your case), you will likely want to do a .Single() on the keys enumeration.

[Test]
public void Test()
{
    var dictionary = new Dictionary<string, int>
                         {
                             { "first", 2 },
                             { "second", 1 },
                             { "third", 3 },
                             { "fourth", 1 }
                         };

    int min = dictionary.Values.Min();
    IEnumerable<string> keys = dictionary.Keys.Where(key => dictionary[key] == min);

    Assert.That(keys.Count(), Is.EqualTo(2));
    Assert.That(keys.Contains("second"), Is.True);
    Assert.That(keys.Contains("fourth"), Is.True);
}

Upvotes: 1

sebagomez
sebagomez

Reputation: 9599

If you order them by the Value the first one will be the one with the minimum

h_scores.OrderBy(x => x.Value).First().Select(y=> y.Key);

Upvotes: 1

Related Questions