【问题标题】:Sort array of structs by a type and then alphabetically by another property按类型对结构数组进行排序,然后按另一个属性按字母顺序排序
【发布时间】:2019-10-22 09:29:21
【问题描述】:

假设我有以下设置。

我正在尝试按字母顺序和category[first, second, third] 进行排序。

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

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

但这完全是一场灾难。

最终结果应该是排序后的标题为foobarbaz

    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]

【问题讨论】:

  • 将它们的特征和其余部分分开,而不是对这两个数组进行排序
  • 它们将代表一个提要,我应该在排序后合并吗?他们会失去订单吗?
  • 数组不会丢失顺序,只需将它们与+连接起来

标签: arrays swift sorting


【解决方案1】:

更具可扩展性的解决方案

当您进行嵌套排序时,您需要先对项目进行分组,然后再按这些组进行排序。例如,我们可以通过将enum 约束到Int 来定义具有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) } }

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

【讨论】:

    【解决方案2】:

    如果您还希望在 .featured 类别中过滤文章(除了在其余部分之前列出精选):

    let res = output.sorted {
        if $0.category == $1.category {
            return $0.title < $1.title
        } else {
            return $0.category == .featured
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2021-12-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-01-26
      • 2018-11-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多