我需要根据最小值从List<KeyValuePair<Int, Int>>
列表中获取Kvp。从KeyvaluePairs列表中获取一个KeyValuePair,其最小值为
我已经试过这样:
KeyValuePair<Int, Int> kvp= listOfKvps.Min(e=> e.Key);
但这仅返回值,而不是整个KeyValuePair
这是我需要的。
我需要根据最小值从List<KeyValuePair<Int, Int>>
列表中获取Kvp。从KeyvaluePairs列表中获取一个KeyValuePair,其最小值为
我已经试过这样:
KeyValuePair<Int, Int> kvp= listOfKvps.Min(e=> e.Key);
但这仅返回值,而不是整个KeyValuePair
这是我需要的。
没有内置MinBy
方法,所以你可以要么写MinBy
扩展方法,或者只是.OrderBy(x => x.Key).First()
。一个MinBy
会O(n)
这样会更有效率 - 但更多的代码编写,P
例如,你可以使用:
var kvp= listOfKvps.MinBy(e=> e.Key);
有:
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;
}
}
}
如果您使用MoreLINQ,则无需编写更多代码:morelinq.googlecode.com :) – 2010-11-17 15:08:14
[Rx](http://thedailywtf.com/Articles/Extensible-XML.aspx)确实在“EnumerableEx”中添加了一个MinBy扩展方法类。所以人们可以期待该框架的未来版本。 – Richard 2010-11-17 15:11:25
var min = listOfKvps.OrderBy(kvp => kvp.Key).First();
如果你想用一个单一的为O(n)穿过的序列,而不是要求一个为O(n log n)的排序,那么你可以不喜欢这样做:
var min = listOfKvps.Aggregate((agg, kvp) => (kvp.Key < agg.Key) ? kvp : agg);
(当然,第二个版本是比第一更可读/直观的,即使它有更好的理论性能这将更有意义使用某种MinBy
方法:要么写你自己的, use the version from Marc's answer或use the version from MoreLINQ。)
我会建议你使用从MoreLinq的MinBy
扩展方法。
或者:
var minKey = listOfKvps.Min(kvp => kvp.Key);
var minKvp = listOfKvps.First(kvp => kvp.Key == minKey);
这仍然是O(n)
,虽然需要2个越过列表。对列表进行排序,然后选择第一个元素更简洁,但是是O(n * logn)
,这可能与较大的列表有关。
该陈述似乎矛盾。如果你没有取回KeyValuePair,那么这个代码甚至不会编译。 – Dave 2010-11-17 15:04:54
@Dave - 但它清楚地描述了OP想要做什么。我宁愿**有一个不编译但显示意图的例子,而不是编译的例子,但无法理解这个问题。 – 2010-11-17 15:11:50