如何在swift中按数字和字母值对字符串数组进行排序



我正在尝试对这样列出的数组进行排序:

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小时制

最新更新