我有一个包含名为HistoryObject
的对象的数组,它具有“date”,“name”等属性。
我正在对数组进行排序:
let sortedArray = HistoryArray.sort({ $0.date.compare($1.date) == NSComparisonResult.OrderedDescending})
应该将日期从较新到最旧排序。例如:
等。
但是当我的数组包含“2016年7月2日”时,排序的数组变为:
“2016年7月2日”排序后应该排在最前面,现在它位于底部?我该如何解决这个问题?
答案 0 :(得分:69)
使用Swift 4&斯威夫特3
let testArray = ["25 Jun, 2016", "30 Jun, 2016", "28 Jun, 2016", "2 Jul, 2016"]
var convertedArray: [Date] = []
var dateFormatter = DateFormatter()
dateFormatter.dateFormat = "dd MM, yyyy"// yyyy-MM-dd"
for dat in testArray {
let date = dateFormatter.date(from: dat)
if let date = date {
convertedArray.append(date)
}
}
var ready = convertedArray.sorted(by: { $0.compare($1) == .orderedDescending })
print(ready)
使用Swift 2
例如,您拥有包含日期的数组和另外1个数组,您将保存转换后的日期:
var testArray = ["25 Jun, 2016", "30 Jun, 2016", "28 Jun, 2016", "2 Jul, 2016"]
var convertedArray: [NSDate] = []
之后我们转换日期:
var dateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "dd MM, yyyy"// yyyy-MM-dd"
for dat in testArray {
var date = dateFormatter.dateFromString(dat)
convertedArray.append(date!)
}
结果:
var ready = convertedArray.sort({ $0.compare($1) == .OrderedDescending })
print(ready)
答案 1 :(得分:13)
适用于Swift 3
process = subprocess.Popen(cmd, shell=True,stdout=subprocess.PIPE)
for line in iter(process.stdout.readline, ''):
print line
答案 2 :(得分:5)
避免使用convertedArray的额外变量
使用Swift 4&斯威夫特3
let testArray = ["25 Jun, 2016", "30 Jun, 2016", "28 Jun, 2016", "2 Jul, 2016"]
var dateFormatter = DateFormatter()
dateFormatter.dateFormat = "dd MM, yyyy"// yyyy-MM-dd"
var ready = convertedArray.sorted(by: { dateFormatter.date(from:$0).compare(dateFormatter.date(from:$1)) == .orderedDescending })
print(ready)
答案 3 :(得分:1)
您有一个数组historyArray
,其中包含HistoryObject
的数组。每个HistoryObject
包含一个日期字符串,格式为“ MM dd,yyyy”
(您要按历史记录对象的日期值对它们进行排序。尝试按日期字符串对具有日期 strings 的对象进行排序是一个坏主意,因为您必须将日期字符串转换为每次比较都使用可可Date
对象,因此最终要一遍又一遍地将日期转换为日期对象,在我做的基准测试中,这导致排序运行的速度比批量转换日期字符串时慢了1200倍到Date
对象进行排序之前,如下所述。)
为了高效地执行此操作,您需要首先获取所有对象的Date
值。一种方法是将Date
惰性变量添加到HistoryObject
中,该变量是根据日期字符串计算得出的。如果您不想这样做,可以:
zip()
函数将历史对象数组与
将日期对象数组转换为元组数组。 执行该操作的代码可能如下所示:
var dateFormatter = DateFormatter()
dateFormatter.dateFormat = "MM dd, yyyy"
//I don't know what your HistoryObject looks like, so I'll fake it.
struct HistoryObject: CustomStringConvertible {
let dateString: String
let value: Int
var description: String {
return "date: \(dateString), value: \(value)"
}
}
//Create an array of date strings.
let testArray = ["Jun 25, 2016", "Jun 30, 2016", "Jun 28, 2016", "Jul 2, 2016"]
//Use the array of date strings to create an array of type [HistoryObject]
let historyArray: [HistoryObject] = testArray.map {
let value = Int(arc4random_uniform(1000))
return HistoryObject(dateString: $0, value: value)
}
print("\n-----> Before sorting <-----")
historyArray.forEach { print($0) }
//Create an array of the `Dates` for each HistoryObject
let historyDates: [Date] = historyArray.map { dateFormatter.date(from: $0.dateString)!
}
//Combine the array of `Dates` and the array of `HistoryObjects` into an array of tuples
let historyTuples = zip(historyArray, historyDates)
//Sort the array of tuples and then map back to an array of type [HistoryObject]
let sortedHistoryObjects = historyTuples.sorted { $0.1 > $1.1}
.map {$0.0}
print("\n-----> After sorting <-----")
sortedHistoryObjects.forEach { print($0) }
如果将lazy var date
添加到HistoryObject中,则排序代码会更简单:
//I don't know what your HistoryObject looks like, so I'll fake it.
class HistoryObject: CustomStringConvertible {
let dateString: String
lazy var date: Date = { dateFormatter.date(from: self.dateString)! }()
let value: Int
var description: String {
return "date: \(dateString), value: \(value)"
}
init(dateString: String, value: Int) {
self.dateString = dateString
self.value = value
}
}
//Create an array of date strings.
let testArray = ["Jun 25, 2016", "Jun 30, 2016", "Jun 28, 2016", "Jul 2, 2016"]
//Use the array of date strings to create an array of type [HistoryObject]
let historyArray: [HistoryObject] = testArray.map {
let value = Int(arc4random_uniform(1000))
return HistoryObject(dateString: $0, value: value)
}
print("\n-----> Before sorting <-----")
historyArray.forEach { print($0) }
let sortedHistoryArray = historyArray.sorted { $0.date > $1.date }
print("\n-----> After sorting <-----")
sortedHistoryArray.forEach { print($0) }
答案 4 :(得分:1)
请试试这个,它对我有用
let sortArr = prescriptionList?.medicationList?.sorted(by:{
($0.medicationDate?.stringDateToInt(requireFormatter: "yyyy-MM-dd HH:mm:ss", needFormatter: "yyyy-MM-dd HH:mm:ss", dateStr: $0.medicationDate ?? ""))! > $1.medicationDate!.stringDateToInt(requireFormatter: "yyyy-MM-dd HH:mm:ss", needFormatter: "yyyy-MM-dd HH:mm:ss", dateStr: $1.medicationDate ?? "")
} )
extension String {
func stringDateToInt(requireFormatter: String, needFormatter: String, dateStr: String) -> Int {
var dateInt: Int = 0
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "\(requireFormatter)"
if let date = dateFormatter.date(from: dateStr) {
dateFormatter.dateFormat = "\(needFormatter)"
dateInt = date.millisecondsSince1970
}
return dateInt
}
}
答案 5 :(得分:0)
您可能要使用“ .sort”而不是“ .sorted”:
convertedArray.sort { (($0)?.compare($1))! == .orderedDescending }
答案 6 :(得分:0)
struct Test {
let dateStr: String
}
let testObjects = ["25 Jun, 2016", "30 Jun, 2016", "28 Jun, 2016", "12 Jul, 2016"]
.map(Test.init(dateStr:))
DateFormatter
:var dateFormatter = DateFormatter()
dateFormatter.locale = Locale(identifier: "en_US_POSIX")
dateFormatter.timeZone = TimeZone(abbreviation: "UTC")
dateFormatter.dateFormat = "dd MMM, yyyy"
map
将每个项目复制到一个元组(测试,日期),然后按日期sort
整个数组,然后再次map
到测试对象:let convertedObjects = testObjects
.map { return ($0, dateFormatter.date(from: $0.dateStr)!) }
.sorted { $0.1 > $1.1 }
.map(\.0)
以类似的方式,我们可以将日期数组排序为字符串:
let testArray = ["25 Jun, 2016", "30 Jun, 2016", "28 Jun, 2016", "12 Jul, 2016"]
DateFormatter
:var dateFormatter = DateFormatter()
dateFormatter.locale = Locale(identifier: "en_US_POSIX")
dateFormatter.timeZone = TimeZone(abbreviation: "UTC")
dateFormatter.dateFormat = "dd MMM, yyyy"
map
将每个项目保留为Date,然后sort
整个数组:let convertedArray = testArray
.compactMap(dateFormatter.date(from:))
.sorted(by: >)