我需要根據最小值從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