Counting sort in Swift I have this sorting algorithm which takes an array of dictionary values:

guard var imageUrlString = anyImage.value as? [String:AnyObject] else { return }


I then loop through it, adding the values with the smallest Int key to a new array to be used afterward. Thus the values in this array of AnyObjects would go from 1 to n.

I was wondering if I could make it more concise.

var values = [AnyObject]()
var keys = [String]()
var Done = false
var j = 1

 while !Done {
    for i in imageUrlString {
        let key = Int(String(i.key.last!))

        if j == key {
            values.append(i.value)
            keys.append(i.key)
            print(i, " This is the i for in if ")
            if imageUrlString.count == j {
                print("Done yet: yes", values[0], " ", values[3])
                Done = true
                break;
            }
            j+=1
        } else {
            print("No,,.")
        }
    }
}
Consider:

let dictionary = ["3": "c", "1": "a", "2": "b”]


If you want to get separate arrays of keys and values, sorted by the order of the Int values of the keys, you can do:

let (keys, values) = dictionary.map { (Int($0.key) ?? 0, $0.value) }  // get `Int` keys
    .sorted { $0.0 &lt; $1.0 }                                           // now sort by those `Int` values
    .reduce(into: ([Int](), [String]())) { arrays, entry in           // divide that up into two arrays
        arrays.0.append(entry.0)
        arrays.1.append(entry.1)
}


That results in a keys of [1, 2, 3] and values of ["a", "b", "c"].

But a key observation is that you actually have to explicitly sort your results. Dictionaries, unlike arrays, are unordered. E.g. regardless of what order the keys appeared in a dictionary literal or JSON, when you iterate through the key-value pairs in a dictionary, the order may be different. You have to convert to an array and sort it yourself if order is important.



The above arbitrarily uses 0 for any keys (if any) that couldn’t be converted to an Int. If you just wanted to drop those entries, you could alternatively do:

let (keys, values) = dictionary.compactMap { entry in Int(entry.key).map { ($0, entry.value) } }
    .sorted { $0.0 &lt; $1.0 }                                       // now sort by those `Int` values
    .reduce(into: ([Int](), [String]())) { arrays, entry in       // divide that up into two arrays
        arrays.0.append(entry.0)
        arrays.1.append(entry.1)
}