用日期键对字典数组进行排序

时间:2019-07-30 06:29:41

标签: ios arrays swift sorting

我正在快速进行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
    },
)

6 个答案:

答案 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
})