需要帮助简化LINQ查询:选择首选类型的项目

时间:2012-11-27 01:38:45

标签: c# linq refactoring

使用单个LINQ表达式可以完成以下操作吗?我有一个项目列表:

public enum ItemType
{
    Top,
    Bottom,
    Side,
    CornerBottom,
    CornerTop
}

public class Item
{
    public int ID;
    public ItemType Type;
}

我想根据ItemType选择一个Item--但是,CornerBottom和CornerTop有一个特例。如果我正在搜索CornerBottom项目,并且没有这样的结果,我会改为喜欢Bottom Item。如果有结果,那么我想要一个Side Item。与CornerTop一样,我首先选择CornerTop项目,然后选择Top第二,然后选择Side第三。

这可以用一个表达式完成吗?现在我有一个处理每个ItemType的switch语句。然而,这是笨拙的,因为实际上我的Item类更复杂(我有更多的ItemTypes),并且我有很多不同的查询需要这个核心功能。

编辑: 好的,我的最终解决方案就是这个。我按照Spencer的建议,使用我的首选搜索顺序重新排序了ItemType枚举。然后我将自定义比较代码放在另一个函数中(这将很容易重用),只需命令并返回第一个值。

ItemType searchType = ItemType.CornerTop;

var i = (from item in Items
        where typeCheck(item, searchType)
        orderby item.Type descending).FirstOrDefault();

bool typeCheck(Item item, ItemType type)
{
    switch (type)
    {
        case ItemType.CornerTop:
            return (item.Type == ItemType.CornerTop)
                || (item.Type == ItemType.Top)
                || (item.Type == ItemType.Side);
        case ItemType.CornerBottom:
            return (item.Type == ItemType.CornerBottom)
                || (item.Type == ItemType.Bottom)
                || (item.Type == ItemType.Side);
        default:
           return item.Type == type;
    }
}

2 个答案:

答案 0 :(得分:2)

按优先顺序给每个枚举值一个数值。按类型对项目列表进行排序,然后抓住第一个项目。

答案 1 :(得分:1)

您可以构建两个平衡树。 CornerTop订购的第一棵树 - >顶部 - >侧。第二个是CornerBottom - >底部 - >侧。如果您搜索CornerTop或CornerBottom,您可以获取树中的第一个项目项。如果您搜索其他类型 - 您可以通过日志(N)直接搜索。 在LINQ上,您可以对集合进行排序并抓取第一个或通过二进制搜索算法进行搜索。