我正在快速进行iOS项目4。 我有一系列类似字典的字典
var myArray = [[String: AnyObject]]()
字典包含名称,年龄,创建年龄(字符串中的日期),国籍等。 而且我需要以“ created_at”键的升序对myArray进行排序,这是日期的字符串格式。我怎样才能做到这一点?请帮我。我检查了所有解决方案,但没有得到排序的数组。
我的数组就像
(
{
name: X
age: 26
created_at: "1991-10-10 18:29:05"
nationality: Indian
},
{
name: Y
age: 30
created_at: "2000-05-10 18:29:05"
nationality: Indian
},
)
答案 0 :(得分:3)
您可以使用此:
let sortedArray = (array as NSArray).sortedArray(using: [NSSortDescriptor(key: "created_at", ascending: true)]) as! [[String:AnyObject]]
只需用if let
包裹起来,以免强制转换。
但是我建议您为此字典创建一个模型,尤其是因为您将要重复使用它与多个数据。
对对象数组进行排序(类似于我在下面发布的内容)比较容易:
编辑:按Date
而不是String
排序日期。下面的代码假定您的createdAt
已被转换为Date对象。
array.sorted(by: { ($0.createdAt).compare($1.createdAt) == .orderedAscending })
答案 1 :(得分:3)
我建议为这些模型创建一个模型,但是当然您也可以这样做
array.sort { (firstItem, secondItem) -> Bool in
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
if let dateAString = firstItem["created_at"] as? String,
let dateBString = secondItem["created_at"] as? String,
let dateA = dateFormatter.date(from: dateAString),
let dateB = dateFormatter.date(from: dateBString){
return dateA.compare(dateB) == .orderedAscending
}
return false
}
答案 2 :(得分:0)
您可以使用 NSSortDescriptor
let sortedArray = (myArray as NSArray).sortedArray(using: [NSSortDescriptor(key: "created_at", ascending: true)]) as! [[String:AnyObject]]
工作示例
let dateDICT = [["name" : "a", "date": "1991-10-10 18:29:05"],["name" : "b", "date": "2000-05-10 18:29:05"],["name" : "c", "date": "2000-05-10 18:29:04"]]
print(dateDICT)
排序前
[["name": "a", "date": "1991-10-10 18:29:05"], ["name": "b", "date": "2000-05-10 18:29:05"], ["name": "c", "date": "2000-05-10 18:29:04"]]
此处第三个元素的日期小于第二个元素的一秒。
排序代码
let sortedArray = (dateDICT as NSArray).sortedArray(using: [NSSortDescriptor(key: "date", ascending: true)]) as! [[String:AnyObject]]
print(sortedArray)
排序后的结果
[["name": a, "date": 1991-10-10 18:29:05], ["name": c, "date": 2000-05-10 18:29:04], ["name": b, "date": 2000-05-10 18:29:05]]
答案 3 :(得分:0)
在您的情况下,键created_at: "1991-10-10 18:29:05"
是日期字符串,因此必须将日期字符串转换为Date
对象,并使用Date().timeIntervalSince1970
方法获取时间间隔。它将返回Double
,您可以使用此Double
值比较日期。
为方便起见,请参阅以下代码段。
//Model For your JSON
struct MyModel:Codable {
var age:Int?
var name:String?
var nationality:String?
var created_at:String?
}
//MY Array
var dataSource = [MyModel]()
//Helper method to convert the date string into timeInterval
func getMilisecFrom(dateString:String) -> Double{
let formator = DateFormatter()
formator.dateFormat = "yyyy-MM-dd HH:mm:ss"
guard let date = formator.date(from: dateString)
else {
return Date().timeIntervalSince1970
}
return date.timeIntervalSince1970
}
// method to short the array
func ShortByDate(){
let shortedData = dataSource.sorted(by: {(getMilisecFrom(dateString: $0.created_at ?? "")) > (getMilisecFrom(dateString: $1.created_at ?? ""))})
dataSource = shortedData
}
答案 4 :(得分:0)
要获得正确的结果,请根据Date
等式逻辑,但不是字符串进行排序。为此,您应该首先从字符串中获取Date
,方法是了解给定日期的所需格式(在您的情况下为yyyy-MM-dd HH:mm:ss
),然后根据该日期对其进行排序。示例:
let myArray: [[String: AnyObject]] = [["name": "X" as AnyObject, "age": 26 as AnyObject, "created_at": "1991-10-10 18:29:05" as AnyObject],
["name": "Y" as AnyObject, "age": 30 as AnyObject, "created_at": "2000-05-10 18:29:05" as AnyObject]]
let formatter = DateFormatter()
formatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
let sorted = myArray.sorted { first, second -> Bool in
guard let firstCreatedAt = first["created_at"] as? String,
let firstCreatedAtDate = formatter.date(from: firstCreatedAt),
let secondCreatedAt = second["created_at"] as? String,
let secondCreatedAtDate = formatter.date(from: secondCreatedAt) else {
return false
}
return firstCreatedAtDate < secondCreatedAtDate
}
print(sorted)
// [["name": X, "age": 26, "created_at": 1991-10-10 18:29:05], ["created_at": 2000-05-10 18:29:05, "name": Y, "age": 30]]
由于Date
符合Comparable
协议,因此您可以简单地使用>
或<
运算符在两个日期之间进行比较。
注意: 日期字符串比较也将起作用。因此,您只需将return firstCreatedAtDate < secondCreatedAtDate
替换为return firstCreatedAt < secondCreatedAt
。
答案 5 :(得分:0)
您使用苹果的排序功能。我们只需要比较
created_at
字段。因为当我们比较字符串时要依靠ASCII进行比较。
let result = myArray.sorted(by: { (object1, object2) in bool
guard let temp1 = object1["created_at"] as? String,
let temp2 = object2["created_at"] as? String else { return false }
return temp1 < temp2
})