Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/265.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何使用linq查找最小值_C#_Linq - Fatal编程技术网

C# 如何使用linq查找最小值

C# 如何使用linq查找最小值,c#,linq,C#,Linq,我有一个a类{public float Score;..}和一个I可数项目,我想找到得分最低的a 使用items.Min(x=>x.Score)给出最小分数,而不是具有最小分数的实例 如何通过在数据中只迭代一次来获取实例 编辑:只要有三种主要解决方案: 编写扩展方法(由Svish提出)。优点:易于使用,每个项目只评估一次分数。缺点:需要一个扩展方法。(我为我的应用程序选择了此解决方案。) 使用骨料(由Daniel Renshaw提出)。优点:使用内置LINQ方法。缺点:对未经训练的人来说有点模

我有一个
a类{public float Score;..}
和一个
I可数项目
,我想找到得分最低的
a

使用
items.Min(x=>x.Score)
给出最小分数,而不是具有最小分数的实例

如何通过在数据中只迭代一次来获取实例

编辑:只要有三种主要解决方案:

  • 编写扩展方法(由Svish提出)。优点:易于使用,每个项目只评估一次分数。缺点:需要一个扩展方法。(我为我的应用程序选择了此解决方案。)

  • 使用骨料(由Daniel Renshaw提出)。优点:使用内置LINQ方法。缺点:对未经训练的人来说有点模糊,并且不止一次打电话给评估者

  • 实现IComparable(由cyberzed提出)。优点:可以直接使用Linq.Min。缺点:固定为一个比较器-执行最小计算时不能自由选择比较器


尝试
items.OrderBy(s=>s.Score.FirstOrDefault()

在我看来,最快的方法是为您的A类实现IComparable(当然,如果可能的话)


class A:i可比参考指南

杰米·彭尼得到了我的投票。你也可以说

items.OrderBy(s => s.Score).Take(1);

这也有同样的效果。使用Take(5)取最低的5等。

这可以通过一个简单的迭代来解决:

float minScore = float.MaxValue;
A minItem = null;

foreach(A item in items)
{
   if(item.Score < minScore)
       minItem = item;
}

return minItem;
float minScore=float.MaxValue;
A minItem=null;
foreach(项目中的项目)
{
如果(item.Score

这不是一个很好的LINQ查询,但它确实避免了排序操作,并且根据问题的要求只迭代列表一次。

看看中的MinBy扩展方法(由Jon Skeet创建,现在主要由Atif Aziz维护)

  • (它非常简单,不依赖于其他文件)

使用骨料:

items.Aggregate((c, d) => c.Score < d.Score ? c : d)
items.Aggregate((c,d)=>c.Score
正如建议的那样,精确的同一行中有更友好的名称:

items.Aggregate((minItem, nextItem) => minItem.Score < nextItem.Score ? minItem : nextItem)
items.Aggregate((minItem,nextItem)=>minItem.Score
稍微折叠一下就可以了:

var minItem = items.Aggregate((acc, c) => acc.Score < c.Score? acc : c);
var minItem=items.Aggregate((acc,c)=>acc.分数


啊。。。太慢。

简洁,但要小心分类;这是一个“缓慢”的操作。如果元素的数量很大,我建议进行基准测试,以确保性能是可接受的。这不会只迭代一次!这是O(n log n)而不是O(n)。检查Svish的答案。我正要写一个扩展方法,它完全符合Jon Skeet已经做过的。RE:“这不会只迭代一次!”这是真的。但它确实回答了我来到这一页的问题:“如何使用linq来找到最小值。”而且,是的,订购大量商品时会付出代价。这是一个好主意。但是如果我有分数1和分数2,并且想改变我用来寻找最小值的分数呢?嗯,这取决于……不知何故,我不介意让对象知道它的比较基础是什么,但我可以理解为什么你会喜欢它的概念。我想说,乔恩·斯基特的方式在明比身上是显而易见的。我想知道这个模式是否可以用linq表示……答案是,没有linq不提供
MinItem
操作。如果您希望有同样简洁的内容,可以将我的答案封装在扩展方法中。或者,如果您对列表进行了两次传递,您可以使用LINQ来完成;应该是{minItem=item;minScore=item.Score;}排序不会只迭代一次!RE:“排序不会只迭代一次!”这是真的。但它确实回答了我来到这一页的问题:“如何使用linq来找到最小值。”而且,是的,订购大量商品时会付出代价。有趣的答案。但是它非常不透明-如果我还不知道它在做什么,我会对代码的意图感到非常困惑。Jamie:我同意,它符合Danvil的要求,但对于那些不熟悉Hakell或F#等函数式语言的人来说,解析它可能很困难。@Jamie-当代码以
minItem=
开头时就不会了。这有点问题,因为您重新实现了
Min
,但我认为这是一个小问题。这很好:)它只使用linq,只迭代一次。linq的一些新手可能会发现使用更有意义的变量名有助于理解这里发生的事情:
items.Aggregate((minItem,nextItem)=>minItem.Score
。不太好。知道索引对IEnumerable没有直接帮助。在某些情况下,必须使用索引再次迭代以找到所需的实例。该方法的整个主体不能替换为这个吗?返回source.Aggregate((c,d)=>comparer.Compare(选择器(c),选择器(d))<0?c:d)@丹尼尔:你得问问Jon Skeet:p不过其中有些是错误检查,你当然想在这样的库中使用。我看到了细微的区别,在MinBy中,选择器在每个实例中只调用一次,而在Aggregate中调用更频繁。顺便说一句:MinBy操作符也受Rx()的支持
var minItem = items.Aggregate((acc, c) => acc.Score < c.Score? acc : c);