Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

to get a KeyValuePair from a List of KeyvaluePairs with the minimum value

Tags:

c#

.net

I need to get a Kvp from a list of List<KeyValuePair<Int, Int>> depending on the minimum value.

I have tried this:

KeyValuePair<Int, Int> kvp= listOfKvps.Min(e=> e.Key);

but this return only the value, not the whole KeyValuePair which I need.

like image 455
Elena Avatar asked Dec 16 '22 19:12

Elena


2 Answers

var min = listOfKvps.OrderBy(kvp => kvp.Key).First();

If you want to do it with a single O(n) pass through the sequence, rather than requiring an O(n log n) ordering, then you could do it like this:

var min = listOfKvps.Aggregate((agg, kvp) => (kvp.Key < agg.Key) ? kvp : agg);

(Of course, the second version is much less readable/intuitive than the first, even if it does have better theoretical performance. It would make more sense to use some sort of MinBy method: either write your own, use the version from Marc's answer or use the version from MoreLINQ.)

like image 168
LukeH Avatar answered Apr 27 '23 00:04

LukeH


There is no inbuilt MinBy method, so you could either write a MinBy extension method, or just .OrderBy(x => x.Key).First(). A MinBy would be O(n) so would be more efficient - but more code to write ;p

For example, you could use:

var kvp= listOfKvps.MinBy(e=> e.Key);

with:

public static class SomeUtil {
    public static TSource MinBy<TSource, TValue>(
        this IEnumerable<TSource> source, Func<TSource, TValue> selector) {
        using (var iter = source.GetEnumerator())
        {
            if (!iter.MoveNext()) throw new InvalidOperationException("no data");
            var comparer = Comparer<TValue>.Default;
            var minItem = iter.Current;
            var minValue = selector(minItem);
            while (iter.MoveNext())
            {
                var item = iter.Current;
                var value = selector(item);
                if (comparer.Compare(minValue, value) > 0)
                {
                    minItem = item;
                    minValue = value;
                }
            }
            return minItem;
        }
    }   
}
like image 44
Marc Gravell Avatar answered Apr 26 '23 23:04

Marc Gravell