所以...我问过去9年是否发生了变化,现在该问题已经作为10年前的问题和答案的重复项被关闭。
。我知道我可以得到最小的Key
,然后使用它。像这样:
theEnumerable[theEnumerable.Min(a => a.Key)];
但是有直接方法吗?据我所知,还没有9年前。但这是很长一段时间。 (然后刚刚发布了Windows Phone(不是“ Mobile”!)。)
(我也可以OrderBy
然后拿走First()
,但这非常很浪费。)
答案 0 :(得分:0)
因此,您有一系列相似的项目,其中每个项目至少具有一个属性Key
,该属性的类型可以实现IComparable。
您需要从序列中的所有项目中选择属性Key
的值最低的项目。如果有几个具有相同的最低价值,那么您就不在乎得到哪个。
如果这样写,解决方案很简单:
var result = myKeyValuePairs.OrderBy(keyValuePair => keyValuePair.Key).FirstOrDefault();
换句话说:采用原始的keyValuePairs序列。按keyValuePair.Key的值升序排列此序列,从所得序列中取第一个,如果序列为空,则返回null。
尽管这很有效,尽管看起来很容易理解,但是如果只需要最小的第二个,第三个最小的等等,订购第二个最小,第三个最小的不是很有效。
一种更有效的方法是使用Enumerable.Aggregate。不过请小心,此功能仅在确定序列中至少有一个元素时才有效。如果不是,则应首先断言该序列不为空。
if (myKeyValuePairs.Any())
return myKeyValuePairs.Aggregate( (lowestPair, currentPair) =>
(lowestPair.Key <= currentPair.Key) ? lowestPair : currentPair);
else
return null;
但是,由于Any(),您将枚举第一个元素两次。除了每个循环之外,您还要进行分配。
一个甚至更优化的代码(只需精确枚举一次序列)将是扩展功能,例如:
TSource SmallestOrDefault<TSource, TResult>(this IEnumerable<TSource> source,
Func<TSource, Tkey> keySelector)
{
// TODO: check null source or keySelector
IEnumerator<TSource> enumerator = source.GetEnumerator();
if (enumerator.MoveNext())
{
// sequence not empty. The first element is smallest until now
TSource smallestElement = enumerator.Current;
// check the rest of the sequence to see if there are smaller elements
while (enumerator.MoveNext)
{
// there is a next element. Is it smaller?
if (enumerator.Current < smallestElement)
{
// found a new smallest element
smallestElement = enumerator.Current;
}
}
return smallestElement;
}
else
// empty sequence
return null;
}
用法:
var smallestElement = myKeyValuePairs.SmallestOrDefault(
keyValuePair => keyValuePair.Key);