代码之家  ›  专栏  ›  技术社区  ›  Sweeper

我如何根据一对多关系中第一个项的键路径对领域结果进行排序?

  •  1
  • Sweeper  · 技术社区  · 6 年前

    我的模型有一个 GroupOfEvents 与有对多关系的领域对象 Event 通过属性的领域对象 events . 各 事件 有一个 date 财产。

    我有一个 Results<GroupOfEvents> 我想按 日期 事件 . 如果我对一个常规的swift数组进行排序,它看起来像:

    groupsOfEvents.sorted(by: { $0.events.first!.date > $1.events.first!.date })
    

    这是我失败的尝试 结果<GroupOfEvents> :

    groupsOfEvents.sorted(byKeyPath: "events.first.date")
    

    它给出了错误:

    “无法对键路径”events.first.date“排序”:属性”groupofevents.events“属于不支持的类型”array“。”

    我怎样才能按我想要的方式分类?


    你可能会问我的问题:

    为什么要按第一个事件的日期排序?这不是人们通常做的事。

    事实上, 成组事件 包含具有相同日期的事件,因此使用 事件 会工作。

    你为什么不把 日期 属性到 成组事件 ?

    是的,我可以这样做,但我正在寻找替代方法。

    你为什么不摆脱呢 成组事件 把所有的 Events 然后按日期分组?

    虽然所有 事件 在一个 成组事件 有相同的日期。两个不同的事件 成组事件 也可以有相同的日期。还有其他特性可以区分 成组事件 .

    3 回复  |  直到 6 年前
        1
  •  0
  •   Mihai Fratu    6 年前

    从领域的头文件,我看到这个评论:

    集合只能按的属性排序 boolean , Date , NSDate ,单精度和双精度 floating point , integer string 类型。

    这意味着您的事件数组不是受支持的键路径,正如您收到的错误所说的那样。

    更新

    基于 this 回答您可以强制转换类型的对象 Results 一个数组。所以你可以试着用这些方法:

    let groupsOfEventsSortedArray = Array(groupsOfEvents).sorted { $0.events.first!.date > $1.events.first!.date }
    
        2
  •  0
  •   pacification    6 年前

    现在,你不能这样做。它应该在任何“领域限制列表”中描述,但它没有。事实上,Github上有一个关于这个问题的问题: Support of keypath sorting for to-many relationships .

    下面是一些解决问题的方法:

    1. 最好的解决方案是 firstEvent: Event GroupOfEvents 模型。这个 Support sorting by keypath 说,你可以排序 .sorted(byKeyPath: "firstEvent.date") . 但它引入了额外的工作来同步 firstEvent events.first .

    2. 对于程序员来说是最便宜的方法,而且可能是效率最差的方法。 Array 然后排序。很简单,但是正如你所知道的,领域只有在你开始使用它的时候才会给你对象(也就是说,它们放置在 lazy 他们可以去任何地方)。如果你没有大量的数据,这应该很好。


    而且,王国有美好的 NSPredicate Cheatsheet 包括有用的图案,并用粉红点标记支持的箱子。

        3
  •  0
  •   TmKVU    6 年前

    我不确定我是否正确理解了这个问题,但是 Results 类有 sorted 接受一个 Sequence (见 documentation )因此,您只需执行以下操作:

    func sortGroupOfEvents(e1: GroupOfEvents, e2: GroupOfEvents) -> Bool{
        guard let date1 = e1.events.first?.date else {return false}
        guard let date2 = e2.events.first?.date else {return true}
        return date1 > date2
    }
    
    groupsOfEvents.sorted(by: sortGroupOfEvents)
    
    推荐文章