【问题标题】:Sorting an array of strings with multiple conditions对具有多个条件的字符串数组进行排序
【发布时间】:2019-05-03 11:35:25
【问题描述】:

我有一个数组,SetDataList,其中填充了以下信息:

["2019-04-30   Set 1:   8 Reps   55kg", "2019-05-02   Set 1:   5 Reps   70kg", "2019-05-02   Set 2:   4 Reps   70kg", "2019-05-02   Set 3:   2 Reps   75kg"]

我目前正在使用下面的代码对数组进行排序,以便将集合 1、2 和 3 分组并在上面的数组中显示。

SetDataList.sort(by: {$0 < $1})

但是,我还想按日期降序对数组进行排序。我之前使用以下代码执行过此操作,但这种方法会打乱设置顺序。

let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd"

let ordered = SetDataList.sorted { string1, string2 in
    guard let date1 = dateFormatter.date(from: string1), let date2 = dateFormatter.date(from: string2) else { return false }
    return date1 < date2
}

如何实现多种排序?谢谢

【问题讨论】:

  • 先将字符串解析成对象的数组,然后使用Sort array of objects with multiple criteria
  • 请考虑guard 表达式失败并始终返回false。日期格式化程序无关紧要。该数组按前导日期字符串表示排序。
  • 鉴于您之前的问题,看起来这个字符串数组是您自己创建的,所以我认为您应该专注于处理对象,而不是像@MartinR 建议的那样使用它,这样您就可以避免出现问题都这样。

标签: arrays swift sorting


【解决方案1】:

我建议使用结构而不是字符串,例如:

struct SetData {
    let setNumber: Int
    let date: Date
    let reps: Int
    let weight: Int
}

让我们从这个数组开始:

let setDataList = ["2019-04-30   Set 1:   8 Reps   55kg",
                   "2019-05-02   Set 10:   20 Reps   70kg",
                   "2019-05-02   Set 1:   5 Reps   70kg",
                   "2019-05-02   Set 2:   4 Reps   70kg",
                   "2019-05-02   Set 3:   2 Reps   75kg"].shuffled()

假设数组中的字符串都具有相同的格式,您可以这样对setDataList进行排序:

let sorted = setDataList.sorted { string1, string2 in
    let dateDelimiter = string1.index(string1.startIndex, offsetBy: 9)
    let earlierDate =  string1[...dateDelimiter] < string2[...dateDelimiter]

    if earlierDate { return true }

    let firstSetStart = string1.index(string1.startIndex, offsetBy: 17)
    var firstSetEnd = firstSetStart

    while firstSetEnd < string1.endIndex,
        string1[firstSetEnd] != ":" {
        firstSetEnd = string1.index(after: firstSetEnd)
    }

    let secondSetStart = string2.index(string2.startIndex, offsetBy: 17)
    var secondSetEnd = secondSetStart

    while secondSetEnd < string2.endIndex,
        string2[secondSetEnd] != ":" {
            secondSetEnd = string2.index(after: secondSetEnd)
    }

    let sub1 = string1[firstSetStart..<firstSetEnd]
    let sub2 = string2[secondSetStart..<secondSetEnd]

    guard let setNbr1 = Int(sub1), let setNbr2 = Int(sub2) else {
        fatalError("Wrong string structure")
    }

    return setNbr1 < setNbr2
}

你可以这样检查结果:

for element in sorted {
    print(element)
}

哪些打印:

2019-04-30 第 1 组:8 次 55kg
2019-05-02 第 1 组:5 次 70kg
2019-05-02 第 2 组:4 次 70kg
2019-05-02 第 3 组:2 次 75kg
2019-05-02 第 10 组:20 次 70kg

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-03-10
    • 1970-01-01
    • 2013-11-07
    • 1970-01-01
    • 2013-03-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多