Reputation: 3809
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
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
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
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
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