【问题标题】:Need help simplifying a LINQ query: choosing an item of a preferred type需要帮助简化 LINQ 查询:选择首选类型的项目
【发布时间】:2012-11-27 01:38:45
【问题描述】:

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

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

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

我想根据 ItemType 选择一个项目 - 但是,CornerBottom 和 CornerTop 有一个特殊情况。如果我正在搜索 CornerBottom 项目,但没有这样的结果,我会想要一个底部项目。如果有结果,那么我想要一个辅助项目。与 CornerTop 一样,我更喜欢首先使用 CornerTop 项目,然后是 Top,然后是 Side 第三。

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

编辑: 好的,我的最终解决方案是这样的。根据 Spencer 的建议,我使用我喜欢的搜索顺序对 ItemType 枚举进行了重新排序。然后我只是把自定义的比较代码放在另一个函数中(这将很容易重用),然后只需 orderby 并返回第一个值。

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;
    }
}

【问题讨论】:

    标签: c# linq refactoring


    【解决方案1】:

    按优先顺序为每个枚举值赋予一个数值。按类型对项目列表进行排序并获取第一个。

    【讨论】:

    • 这几乎可以工作,但如果我正在搜索 ItemType.Side 类型,我希望它返回 Side 类型的东西,或者什么都不返回。
    • 然后添加一个 Where 条件,表示 ItemType 应该大于 Side。
    • 我基本上按照你说的做了,但是把比较检查放在它自己的函数中。这允许更多的灵活性。我在编辑中发布了最终代码。谢谢!
    【解决方案2】:

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

    【讨论】:

      猜你喜欢
      • 2013-03-27
      • 2014-12-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多