簡體   English   中英

使用日期鍵對字典數組進行排序

[英]Sort an Array of dictionaries with date key

我正在 swift 4 中開發一個 iOS 項目。我有一個類似字典的數組

var myArray = [[String: AnyObject]]()

字典包含姓名、年齡created_at(字符串中的日期)、國籍等。我需要按照日期字符串格式的“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
    },
)

你可以使用這個:

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

我建議為這些創建一個模型,但當然你也可以這樣做

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
}

您可以使用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]]

在您的情況下,鍵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
}

在您的情況下,要獲得正確的結果,您可以根據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

你使用蘋果的排序功能。 我們只需要比較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
})

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM