Jordan
Jordan

Reputation: 329

Sort an array of dictionaries by a certain key value (Swift 3)

I was looking for a way to sort an array of invoice dictionaries based on invoice ID (which is a value of one of the keys in the dictionary). I couldn't find a solution that worked as well as I would've liked so I wrote out a function which works well for me and I thought I'd share it with the community.

It's pretty simple, you just pass in the array, pass in the key to sort it by and it returns the array sorted.

let testArray: Array<Dictionary<String, String>> = sortDictArrayByKey(arr: someUnsortedArray, key: keyToSort)
func sortDictArrayByKey(arr: Array<Dictionary<String, String>>, key: String) -> Array<Dictionary<String, String>>{
    var keyArray = Array<String>()
    var usedKeys = Array<String>()
    for object in arr{
        keyArray.append(object[key]!)
    }

    keyArray.sort(by: <)

    var newArray = Array<Dictionary<String, String>>()
    for keyVal in keyArray{

    // Check if we've already seen this entry, if so, skip it
        if usedKeys.contains(keyVal){
            continue
        }
        usedKeys.append(keyVal)

    // Check for duplicate entries
        var tempArray = Array<Dictionary<String, String>>()
        for object in arr{
            if object[key] == keyVal{
                tempArray.append(object)
            }
        }
        for item in tempArray{
            newArray.append(item)
        }
        tempArray.removeAll()
    }
    return newArray
}

Upvotes: 1

Views: 991

Answers (1)

Luca Angeletti
Luca Angeletti

Reputation: 59506

Extension

You can created an extension available for Arrays of Dictionaries where both the Key and the Value are String(s).

extension Array where Element == [String:String] {
    func sorted(by key: String) -> [[String:String]] {
        return sorted { $0[key] ?? "" < $1[key] ?? "" }
    }
}

Example

let crew = [
    ["Name":"Spook"],
    ["Name":"McCoy"],
    ["Name":"Kirk"]
]

crew.sorted(by: "Name")

// [["Name": "Kirk"], ["Name": "McCoy"], ["Name": "Spook"]]

Upvotes: 2

Related Questions