C# 使用LINQ查找哪个元素";“得分最高”;关于某一函数
如果我有C# 使用LINQ查找哪个元素";“得分最高”;关于某一函数,c#,linq,C#,Linq,如果我有 IEnumerable<Something> IEnumerable 对于一个接受某物并返回int的函数,我如何使用LINQ来告诉我,当输入到我的函数时,哪个某物给出了最高的结果?您可以使用: 请注意,如果使用LINQ to对象,这将导致O(n log n)排序 您还可以从以下位置使用MaxBy: 您可以使用(或简单地使用): public static TSource MaxBy(此IEnumerable源, Func选择器,IComparer(比较器) { 使用(I
IEnumerable<Something>
IEnumerable
对于一个接受某物并返回int的函数,我如何使用LINQ来告诉我,当输入到我的函数时,哪个某物给出了最高的结果?您可以使用:
请注意,如果使用LINQ to对象,这将导致O(n log n)排序
您还可以从以下位置使用MaxBy
:
您可以使用(或简单地使用):
public static TSource MaxBy(此IEnumerable源,
Func选择器,IComparer(比较器)
{
使用(IEnumerator sourceIterator=source.GetEnumerator())
{
如果(!sourceIterator.MoveNext())
抛出新的InvalidOperationException(“序列为空”);
TSource max=sourceIterator.Current;
TKey maxKey=选择器(最大值);
while(sourceIterator.MoveNext())
{
TSource candidate=sourceIterator.Current;
TKey candidateProjected=选择器(候选者);
if(comparer.Compare(candidateProjected,maxKey)>0)
{
max=候选人;
maxKey=候选项目;
}
}
返回最大值;
}
}
此聚合很简单,但每次迭代中对max in调用func方法两次,以避免出现这种情况:
var something=List.Select(p => new { something = p, call = func(p) })
.Aggregate((p, q) => p.call > q.call ? p : q).something;
Max(p=>p.intFunc()) 我使用LINQtoObjects做了一个快速测试,结果表明,对于列表中的每个元素,f(x)只调用一次(尽管排序不同)。@Matthewstrowbridge:是的,我认为你是对的。我认为,
OrderBy
首先调用每个元素上的投影函数,并将结果存储在列表中,然后对其进行排序。因此,它不仅速度慢,而且比MaxBy在MoreLINQ中执行的简单线性搜索消耗的内存要多得多。这就得到了最大的func(p)
。问题是如何找到p
,其中func(p)
给出最大结果。List.Max(p=>func(p))
的结果将是通过调用func
获得的值之一。这不是问题所要求的通话中使用的内容。
Something result = yourEnumerable.MaxBy(x => f(x));
public static TSource MaxBy<TSource, TKey>(this IEnumerable<TSource> source,
Func<TSource, TKey> selector, IComparer<TKey> comparer)
{
using (IEnumerator<TSource> sourceIterator = source.GetEnumerator())
{
if (!sourceIterator.MoveNext())
throw new InvalidOperationException("Sequence was empty");
TSource max = sourceIterator.Current;
TKey maxKey = selector(max);
while (sourceIterator.MoveNext())
{
TSource candidate = sourceIterator.Current;
TKey candidateProjected = selector(candidate);
if (comparer.Compare(candidateProjected, maxKey) > 0)
{
max = candidate;
maxKey = candidateProjected;
}
}
return max;
}
}
var something= List.Aggregate((p, q) => func(p) > func(q) ? p : q)
var something=List.Select(p => new { something = p, call = func(p) })
.Aggregate((p, q) => p.call > q.call ? p : q).something;