首页 > 解决方案 > 按类型对结构数组进行排序,然后按另一个属性按字母顺序排序

问题描述

想象一下我有以下设置。

我正在尝试[first, second, third]按字母顺序排序,也按category.

我首先想要featured项目,然后是按 . 排序的所有其他内容title

我试过let output = [first, second, third].sort { $0.category == $1.category ? $0.category && $1.category == .featured : $0.title < $1.title }

但这完全是一场灾难。

最终结果应该是排序后的标题读取foo bar baz

    enum Category {
        case featured, standard
    }

    struct Article {
        var title: String
        var category: Category
    }

    let first = Article(title: "bar", category: .standard)
    let second = Article(title: "foo", category: .featured)
    let third = Article(title: "boo", category: .standard)

    let output = [first, second, third]

标签: arraysswiftsorting

解决方案


更可扩展的解决方案

嵌套排序后,您需要先对项目进行分组,然后按这些组排序。例如,我们可以Int通过约束enumto来定义类别的优先级Int

enum Category: Int {
    case featured // Higher level(value) -> Higher priority in sort
    case standard // Lower level(value) -> Lower priority in sort
}

现在你应该:

  • 排序前对数据进行分组:
let grouped = Dictionary(grouping: input, by: { $0.category })
  • 排序组:(因此Category案例应该具有可排序的值,例如Int
let sortedGroups = grouped.sorted { $0.key.rawValue < $1.key.rawValue } 
  • 对每个组的数据进行排序并将其映射回原始数组:
let result = sortedGroups.map { $0.value.sorted { $0.title < $1.title) } }

这种方法具有高度可扩展性和自动化。您只需要定义新类别来代替它们的优先级。其余代码始终按预期工作。


推荐阅读