Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/307.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# 如何正确实现IEnumerable以返回按属性排序的项?_C#_.net Core_Ienumerable - Fatal编程技术网

C# 如何正确实现IEnumerable以返回按属性排序的项?

C# 如何正确实现IEnumerable以返回按属性排序的项?,c#,.net-core,ienumerable,C#,.net Core,Ienumerable,我的目标是从匹配Booenum条件的Foo列表中返回第一个Foo项,并且应该按照Boo值对其进行优先级排序,如示例所示,如果没有任何项匹配该条件,则只返回第一个项 模型: class Foo { E_Boo Boo { get; set; } } enum E_Boo { Undefined = 0, Jessie = 1, Abby = 2, Felix = 3, Lacey = 4, Lucia = 5, Anisa = 6

我的目标是从匹配
Boo
enum条件的Foo列表中返回第一个
Foo
项,并且应该按照
Boo
值对其进行优先级排序,如示例所示,如果没有任何项匹配该条件,则只返回第一个项

模型:

class Foo 
{
    E_Boo Boo { get; set; }
}
enum E_Boo
{
    Undefined = 0,
    Jessie = 1,
    Abby = 2,
    Felix = 3,
    Lacey = 4,
    Lucia = 5,
    Anisa = 6    
}
这就是我尝试的,它有效:

    public Foo GetFooByBooPriority(IEnumerable<Foo> foos)
    {
        if(foos.Any(x => x.Boo == E_Boo.Abby))
            return foos.First(x => x.Boo == E_Boo.Abby);
        else if (foos.Any(x => x.Boo == E_Boo.Lacey))
            return foos.First(x => x.Boo == E_Boo.Lacey);
        else if (foos.Any(x => x.Boo == E_Boo.Lucia))
            return foos.First(x => x.Boo == E_Boo.Lucia);
        else if (foos.Any(x => x.Boo == E_Boo.Felix))
            return foos.First(x => x.Boo == E_Boo.Felix);
        else if (foos.Any(x => x.Boo == E_Boo.Anisa))
            return foos.First(x => x.Boo == E_Boo.Anisa);
        else if (foos.Any(x => x.Boo == E_Boo.Jessie))
            return foos.First(x => x.Boo == E_Boo.Jessie);
        else
            return foos.First();
    }
public Foo GetFooByBooPriority(IEnumerable foos)
{
if(foos.Any(x=>x.Boo==E_Boo.Abby))
返回foos.First(x=>x.Boo==E_Boo.Abby);
else if(foos.Any(x=>x.Boo==E_Boo.Lacey))
返回foos.First(x=>x.Boo==E_Boo.Lacey);
else if(foos.Any(x=>x.Boo==E_Boo.Lucia))
返回foos.First(x=>x.Boo==E_Boo.Lucia);
else if(foos.Any(x=>x.Boo==E_Boo.Felix))
返回foos.First(x=>x.Boo==E_Boo.Felix);
else if(foos.Any(x=>x.Boo==E_Boo.Anisa))
返回foos.First(x=>x.Boo==E_Boo.Anisa);
else if(foos.Any(x=>x.Boo==E_Boo.Jessie))
返回foos.First(x=>x.Boo==E_Boo.Jessie);
其他的
返回foos.First();
}
你知道如何在性能和更干净的代码方面改进这个优先检索器吗

更新:

在这种情况下,优先级逻辑需要与enum
E_Boo
定义解耦,换句话说,如果enum定义将被更改,优先级逻辑应该保持smae

我想将实现与枚举值和名称分离

一个简单的解决方案是在代码中添加一个
列表
,并按照所需的
E_Boo
值的顺序填充它:

var booOrder = new List<E_Boo> 
{
    E_Boo.Abby,
    E_Boo.Lacey,
    E_Boo.Lucia,
    E_Boo.Felix,
    // ... And so on
};

foos.OrderBy(x=>x.Boo.FirstOrDefault()
?@vasily.sib看起来像
foos.OrderBy(x=>x.Boo.ToString())
会更好地匹配OP的代码……如果优先级是完全随机的(与您的示例不同),那么针对每个枚举条目的一个具有优先级的属性是您最好的选择。向您展示了如何做到这一点。@ShaharShokrani您可以实现一个
IComparer
并将其传递给
OrderBy
,如下所示:
foos.OrderBy(x=>x.Boo,eBooComparerInstance)。FirstOrDefault()
出于性能原因,您可以在列表上使用计数排序->(只要枚举值是线性的,或者使用每个枚举值只有一位的标志时),就可以使用枚举值作为
Foo
->数组的索引位置,然后在遍历Ienumerable之后,只需遍历列表并返回第一个非空的值。这应该是O(n)而且比普通的(O(n*log(n))更好,实际上您可能不会使用
IndexOf
(由于线性搜索)在实际代码中,但作为解释,它是完美的。@AlexeiLevenkov如果它的值数量足够小,足以容纳一个枚举,我不会期望使用的搜索算法会导致任何性能问题。在性能方面,我可能想在列表上尝试一个数组,但我真的认为在这种情况下它不应该有多大关系。谢谢你不过,您的反馈是:-)如果
booOrder
确实变大了,那么使用字典查找比使用
IndexOf
进行线性搜索要好。不过,现在可能不需要进行这种优化。@RoadRunner我完全同意-但如果枚举变得那么大,那么性能损失可能是您最不担心的:-)
var result = foos.OrderBy(f => booOrder.IndexOf(f.Boo)).First();