Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/292.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# 如何在不进行广泛搜索的情况下基于2个条件获取对象?_C#_.net_Linq_Collections - Fatal编程技术网

C# 如何在不进行广泛搜索的情况下基于2个条件获取对象?

C# 如何在不进行广泛搜索的情况下基于2个条件获取对象?,c#,.net,linq,collections,C#,.net,Linq,Collections,很难将其概括为一行问题。我有一门课是这样的: class Item { int Count {get; set;} double Value {get; set;} } 以及包含任意数量的项值的列表 如何获得项的计数最低,值最高 性能并不重要,但优雅是重要的,因为我不希望有巨大的嵌套循环来执行此操作,除非没有优雅的方式,如Linq等 编辑: 以下是可能包含以下项的示例列表: {Count, Value} {2, 10}, {6, 60}, {5, 21}, {4, 65},

很难将其概括为一行问题。我有一门课是这样的:

class Item
{
    int Count {get; set;}
    double Value {get; set;}
}
以及包含任意数量的
值的
列表

如何获得
计数最低,
值最高

性能并不重要,但优雅是重要的,因为我不希望有巨大的嵌套循环来执行此操作,除非没有优雅的方式,如Linq等

编辑:

以下是可能包含以下
项的示例列表:

{Count, Value}

{2, 10}, {6, 60}, {5, 21}, {4, 65}, {2, 35}, {4, 18}, {3, 55}, {7, 99}, {2, 25}

所以这里我想要的值是
{2,35}
,因为它在所有项目中的
计数最低,对于具有相同
计数
值的项目,它的
值最高

好的,现在我们有点清楚了:

只要它具有最低计数,该范围内的最高值就可以

这很容易

var best = list.OrderBy(x => x.Count)
               .ThenByDescending(x => x.Value)
               .FirstOrDefault();
如果列表为空,则将给出
null
,否则将给出计数最低的项,如果该计数有多个,则给出值最高的项


这比它可能的效率要低,因为我们可以通过创建一个比较器来比较任意两个值,从而在一次过程中真正做到这一点——但这肯定是一种在最少的代码中获得正确元素的方法。

希望它现在可以工作,遗憾的是它没有Jon的那么优雅

var res = (from i in items
           orderby i.Count ascending, i.Value descending
           select i).FirstOrDefault();
使用(具有
MinBy
MaxBy
运算符),您可以在线性时间内轻松完成此操作(遗憾的是需要额外的过程):

编辑

这里有一种(丑陋的)方法,可以使用标准LINQ在O(1)空间和O(n)时间内一次通过:

var minCountItemWithMaxValue = items.Aggregate(
                                (bestSoFar, next) =>
                                (next.Count < bestSoFar.Count) ? next :  
                                (next.Count > bestSoFar.Count) ? bestSoFar :
                                (next.Value > bestSoFar.Value) ? next : bestSoFar);
var minCountItemWithMaxValue=items.Aggregate(
(最佳,下一个)=>
(next.CountbestSoFar.Count)?bestSoFar:
(next.Value>bestSoFar.Value)?next:bestSoFar);

您想取回两个项目,一个是计数最低的项目,另一个是值最高的项目,还是只想返回一个计数最低且来自此项目的值最高的项目?这两个查询是分开的吗?也,它必须是一个
列表
,还是您愿意维护一个专门构建的数据结构,以便在需要时高效地执行所需的查询?@BigL:对不起,我指的是一个
计数最低但
值最高的项目。
@Joan:如果计数最低的项目不是具有最高价值?还是这是一个多目标优化?@Ani:我使用了一个
列表
,但我不确定你的意思。你是说像IEnumerable这样的东西?我想这可能没什么大不了的。谢谢乔恩,这正是我想要的。你所说的比较器是指,在
类中?@JoanVenge:要么制作
实现
IComparer
/
IComparer
,要么提供一个单独的
IComparer
传递给
最大值
最小值
方法。谢谢Jon,顺便说一句,如果我有
IComparer
,那只是出于好奇,我是否可以使用
Min
,并得到相同的结果?只是好奇。我们真的需要一个带有链式比较的
MaxBy
。。。但这很难表达。我必须考虑一下。。。(我确实提到了Myelnq,但觉得在这种情况下是不值得的。)乔恩:<代码> Almin Buy < /Cord>和<代码> AlxMax B/C>比较容易,是吗?它不是理想的,因为您必须保留所有当前具有最小值的项的列表。因此,保持O(1)内存方面是很好的。我确信使用另一个界面是可行的,但是否值得付出努力则是另一回事。@Jon:Btw,“MoreLINQ”而不是“MoreLINQ”是你首选的大写字母吗?我使用“morelinq”是因为这就是它在项目页面上的资本化方式。@Jon:当然,但由于它们是不同的扩展(没有必要去掉
O(1)
space
MinBy
MaxBy
),客户端必须明确要求它接受
O(n)
空格命中。这不起作用。你明白为什么吗?仔细比较你的答案和乔恩的答案。
var minCountItemWithMaxValue = items.AllMinBy(item => item.Count)
                                    .MaxBy(item => item.Value);
var minCountItemWithMaxValue = items.Aggregate(
                                (bestSoFar, next) =>
                                (next.Count < bestSoFar.Count) ? next :  
                                (next.Count > bestSoFar.Count) ? bestSoFar :
                                (next.Value > bestSoFar.Value) ? next : bestSoFar);