按日期排序数组中的对象

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了按日期排序数组中的对象相关的知识,希望对你有一定的参考价值。

我有一个包含一个名为HistoryObject的对象的数组,它有“date”,“name”等属性。

我像这样排序数组:

 let sortedArray = HistoryArray.sort({ $0.date.compare($1.date) == NSComparisonResult.OrderedDescending})

应该将日期从较新到最旧排序。例如:

  • Jun 30, 2016
  • Jun 29, 2016

等等..

但是当我的数组包含“2016年7月2日”时,排序的数组变为:

  • Jun 30, 2016
  • Jun 29, 2016
  • 2016年7月2日

排序后“2016年7月2日”应该排在最前面,现在它位于底部?我该如何解决这个问题?

答案

使用Swift 4和Swift 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)
另一答案

对于Swift 3

var testArray = ["25 Jun, 2016", "30 Jun, 2016", "28 Jun, 2016", "2 Jul, 2016"]
var convertedArray: [Date] = []

var dateFormatter = DateFormatter()
dateFormatter.dateFormat = "dd/MM/yyyy"

for dat in testArray {
    var date = dateFormatter.date(from: dat)
    convertedArray.append(date!)
}

//Approach : 1
convertedArray.sort(){$0 < $1}    

//Approach : 2
convertedArray.sorted(by: {$0.timeIntervalSince1970 < $1.timeIntervalSince1970})

print(convertedArray)
另一答案

避免使用convertedArray的额外变量

使用Swift 4和Swift 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)
另一答案

你有一个数组historyArray,其中包含一个HistoryObject数组。每个HistoryObject都包含“MM dd,yyyy”形式的日期字符串

编辑:

(您希望按日期值对历史对象进行排序。尝试使用日期字符串按日期字符串对对象进行排序是个坏主意,因为您必须将日期字符串转换为Cocoa Date对象进行每次比较,因此您结束我一遍又一遍地将日期转换为日期对象。在我做的基准测试中,这导致排序比在排序之前将日期字符串批量转换为Date对象运行速度快1200倍,如下所述。)

为了有效地执行此操作,您需要首先获取所有对象的Date值。一种方法是在你的Date中添加一个懒惰的HistoryObject变量,它是根据日期字符串计算出来的。如果您不想这样做,您可以:

  1. 使用DateFormatter将历史对象数组映射到Date对象数组。
  2. 使用zip()函数将历史对象数组和日期对象数组合成一个元组数组。
  3. 对元组数组进行排序。
  4. 将元组数组映射回历史对象数组。

执行此操作的代码可能如下所示:

版本1

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("
-----> 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("
-----> After sorting <-----")
sortedHistoryObjects.forEach { print($0) }

如果你将lazy var date添加到HistoryObject中,那么排序代码就更简单了:

版本2:

//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("
-----> Before sorting <-----")
historyArray.forEach { print($0) }

let sortedHistoryArray = historyArray.sorted { $0.date > $1.date }
print("
-----> After sorting <-----")
sortedHistoryArray.forEach { print($0) }

以上是关于按日期排序数组中的对象的主要内容,如果未能解决你的问题,请参考以下文章

iOS小技能:对象数组按照日期分组和排序,使用块代码实现数组排序和乱序。

iOS小技能:对象数组按照日期分组和排序,使用块代码实现数组排序和乱序。

按日期对具有日期字段的对象数组进行排序

Javascript - 按日期然后按时间对对象数组进行排序

按日期对对象的嵌套数组进行排序

按日期排序数组 - javascript [重复]