Swift-一次性按日期和时间对数组进行排序

时间:2019-11-19 15:26:55

标签: arrays swift sorting

我有一个数组,其字符串属性类似于日期(yyyy-MM-dd),而字符串的另一个属性类似于时间(HH:mm)。

我正在尝试按日期对数组进行排序,然后按1次扫描对时间进行排序。

示例:

Array[0].date = 2019-11-18
Array[0].time = 19:00
Array[1].date = 2019-11-18
Array[1].time = 22:00
Array[2].date = 2019-10-14
Array[2].time = 16:00
Array[3].date = 2019-11-16
Array[3].time = 13:00
Array[4].date = 2019-11-16
Array[4].time = 14:00

我想实现

Array[0].date = 2019-11-18
Array[0].time = 22:00
Array[1].date = 2019-11-18
Array[1].time = 19:00
Array[2].date = 2019-10-16
Array[2].time = 14:00
Array[3].date = 2019-10-16
Array[3].time = 13:00
Array[4].date = 2019-11-14
Array[4].time = 16:00.

我该如何使用Swift做到这一点?

非常感谢您的光临!

3 个答案:

答案 0 :(得分:0)

您可以附加日期和时间字符串,因为最大的书本间隔(年)在左侧,最小的(分钟)在右侧。按照标准的字典顺序排序,将把“最大的”日期/时间组合放在第一位。

let sortedArray = myArray.sorted(by: { ($0.date + $0.time) > ($1.date + $1.time) })

答案 1 :(得分:0)

首先,请以小写字母(array)开头的变量命名

由于格式yyyy-MM-dd HH:mm是可排序的,因此只需通过连接字符串即可对数组进行排序。

array.sort{"\($0.date) \($0.time)" > "\($1.date) \($1.time)"}

答案 2 :(得分:0)

此答案是对OP中以下评论中对问题的改进,以回应@vadian的回答。实际要求是对API提供的足球进球时间进行排序。以下解决方案为此数据创建了一个结构,并使用了实际目标时间的计算出的变量,然后按此排序。

struct Goal{
   let matchDate: String
   let matchTime: String
   let goalTime: String

   var timeOfGoal: Date {
      let goalComponents = goalTime.components(separatedBy: "+").map{$0.trimmingCharacters(in: CharacterSet.whitespacesAndNewlines.union(CharacterSet.decimalDigits.inverted))}
      let goalSeconds = TimeInterval(60 * goalComponents.compactMap({Int($0)}).reduce(0, +))
      let dateFormatter = DateFormatter()
      dateFormatter.dateFormat = "yyyy-MM-dd HH:mm"
      let startTime = dateFormatter.date(from: matchDate + " " + matchTime)!
      return startTime.addingTimeInterval(goalSeconds)
   }
}

我如下测试了

let goals = [
   Goal(matchDate: "2019-11-18", matchTime: "22:00", goalTime: "90 +7"),
   Goal(matchDate: "2019-11-18", matchTime: "19:00", goalTime: "22"),
   Goal(matchDate: "2019-11-18", matchTime: "22:00", goalTime: "99"),
   Goal(matchDate: "2019-11-18", matchTime: "19:00", goalTime: "45 + 3"),
   Goal(matchDate: "2019-11-18", matchTime: "19:00", goalTime: "45+6"),
   Goal(matchDate: "2019-11-18", matchTime: "22:00", goalTime: "90+6"),
   Goal(matchDate: "2019-11-18", matchTime: "22:00", goalTime: "35"),
   Goal(matchDate: "2019-11-18", matchTime: "22:00", goalTime: "85"),
   Goal(matchDate: "2019-11-18", matchTime: "22:00", goalTime: "90"),
   Goal(matchDate: "2019-11-18", matchTime: "22:00", goalTime: "90+ 8"),
   Goal(matchDate: "2019-11-18", matchTime: "19:00", goalTime: "44")]

let ordered = goals.sorted{$0.timeOfGoal > $1.timeOfGoal}

ordered.forEach{print("\($0.matchDate) - \($0.matchTime) - \($0.goalTime) ")}

它正确产生了:

2019-11-18 - 22:00 - 99 
2019-11-18 - 22:00 - 90+ 8 
2019-11-18 - 22:00 - 90 +7 
2019-11-18 - 22:00 - 90+6 
2019-11-18 - 22:00 - 90 
2019-11-18 - 22:00 - 85 
2019-11-18 - 22:00 - 35 
2019-11-18 - 19:00 - 45+6 
2019-11-18 - 19:00 - 45 + 3 
2019-11-18 - 19:00 - 44 
2019-11-18 - 19:00 - 22 

尽管可以通过强制清理Date?来解决问题,但仍可以通过使用类级静态DateFormatter来强制解压缩let self = this; fetch('/yourAuthUrl') then(function() { //Wait auth result //HERE UPDATE YOUR STATE WITH TOKEN (i think with connect plugin if u need redux) const req1 = fetch('/yourApiUrlWithToken') const req2 = fetch('/yourApiUrlWithToken') const req3 = fetch('/yourApiUrlWithToken') const req4 = fetch('/yourApiUrlWithToken') Promise.all([req1,req2,req3,req4]) //Wait all api request .then(function() { //HERE UPDATE YOUR STATE FOR RENDER (i think with connect plugin if u need redux) }); }) 。但我会留待实施的改进:-)