我正在尝试对这样列出的数组进行排序:
let array = ["02:00 AM", "01:00 AM", "01:00 PM", "01:01 AM", "01:01 PM", "03:00 AM"]
这是一系列时间,我可以在我的userDefaults中添加/更新提醒,但我希望它不仅按时间排序,而且按AM/PM值排序。这样阵列看起来是这样的:
["01:00 AM", "01:01 AM", "02:00 AM", "03:00 AM", "01:00 PM","01:01 PM"]
我该怎么做?在数组上使用.sort()
不起作用,因为它只会按时间排序,但我特别希望AM字符串在PM字符串之前。我把数组作为字符串,因为我认为这会更容易,但我发现这可能不是最好的方法
基于@nighttalker的答案,您可以使用sorted(by: <)
在一行中得到它。
那么代码将是:
let array = ["02:00 AM", "01:00 AM", "01:00 PM", "01:01 AM", "01:01 PM", "03:00 AM"]
let sortedArray = array.filter { $0.contains("AM") }.sorted(by: <) + array.filter { $0.contains("PM") }.sorted(by: <)
但正如Arkku所说,您可能应该使用Date类型,并使其符合Comparable。
(我还不能发表评论,所以不得不以这种方式提交(
按12&AM,然后排序。按12&PM,然后排序。然后加入2个数组。
let array = ["12:00 AM", "12:02 PM", "02:00 AM", "01:00 AM", "01:00 PM", "01:01 AM", "01:01 PM", "03:00 AM"]
我们需要考虑#12将影响排序。所以你需要把所有的时间都用12过滤掉,把它们分类,然后放在前面。
let amc = array.filter { $0.hasPrefix("12") }.filter { $0.hasSuffix("AM") }.sorted(by: <) + array.filter { !$0.hasPrefix("12") }.filter { $0.hasSuffix("AM") }.sorted(by: <)
let pmc = array.filter { $0.hasPrefix("12") }.filter { $0.hasSuffix("PM") }.sorted(by: <) + array.filter { !$0.hasPrefix("12") }.filter { $0.hasSuffix("PM") }.sorted(by: <)
let comb = amc + pmc
print(comb) // prints ["12:00 AM", "01:00 AM", "01:01 AM", "02:00 AM", "03:00 AM", "12:02 PM", "01:00 PM", "01:01 PM"]
通过这个练习,很明显使用Date
是最好的方法。
let morningTimes = arrayOfTimes.filter{$0.contains("AM") && !$0.contains("12:")}.sorted()
let dayTimes = arrayOfTimes.filter{$0.contains("12:") && $0.contains("AM")}.sorted() + morningTimes
let nightTimes = arrayOfTimes.filter{$0.contains("PM") && !$0.contains("12:")}.sorted()
let allTimes = dayTimes + arrayOfTimes.filter{$0.contains("12:") && $0.contains("PM")}.sorted() + nightTimes
您可以将sort
传递给一个块,并在那里实现比较逻辑,例如:
var array = ["02:00 AM", "01:12 AM", "01:00 PM", "01:01 AM", "01:01 PM", "03:00 AM", "12:15 AM", "12:30 AM", "12:01 PM", "12:30 PM" ]
array.sort { s1, s2 in
let isAM1 = s1.contains("AM")
let isAM2 = s2.contains("AM")
return isAM1 && !isAM2 || ((isAM1 == isAM2) && s1 < s2)
}
当且仅当第一个参数在第二个参数之前排序时,比较块应返回true
。这在这里被实现为使得第一个是AM并且第二个是PM,或者两者都是相同的AM/PM并且第一个具有更早的时间。
第页。S.您可以首先考虑使用Date
对象而不是字符串(您可以随时根据需要将它们格式化回字符串(。
编辑:如果字符串使用"12:00 PM"为中午、"12:00 AM"为午夜的约定,则上述时间将被错误排序。你可以通过测试s1.hasPrefix("12:")
并反转"is AM"状态来解决这个问题:
if s1.hasPrefix("12:") {
isAM1 = !isAM1
}
if s2.hasPrefix("12:") {
isAM2 = !isAM2
}
即使这种方法也会将12:59 AM
排在最后,而不是排在01:00 AM
之前——如果这是一个问题,您可以微调比较。然而,我认为仅凭这种复杂性就足以使用Date
对象(或您自己的Comparable
时间持有者(而不是字符串。假设你不愿意换成24小时制