swiftcollectionstype-conversionordereddictionary

How can I initialize an OrderedDictionary from a regular Dictionary in Swift?


Apples swift-collections package provides an alternative to a Dictionary type which guarantees to keep (not bring) its key-value pairs in order (unlike the regular Dictionary type). But how can I turn an instance of type Dictionary into an instance of type OrderedDictionary for later re-ordering?

For example, how would it work for this dict:

let regularDict: [String: String] = ["key1": "value1", "key2": "value2"]
// => EITHER {key2=>value2, key1=>value1} OR {key1=>value1, key2=>value2}

let orderedDict: OrderedDictionary<String, String> = .init(/* ??? */)

I am aware that orderedDict will have a random order of key-value entries at first, that's fine for me, I just need an OrderedDictionary instance so any future changes to the order I make don't get lost. I just want to know how to initialize it from a Dictionary in a way that is performant and makes sure the keys stay connected to the correct values.


Solution

  • You can use init(uniqueKeys:values:) with the regular dictionaries' keys and values:

    let regularDict = ["key1": "value1", "key2": "value2"]
    // => EITHER {key2=>value2, key1=>value1} OR {key1=>value1, key2=>value2}
    
    var orderedDict = OrderedDictionary<String, String>(
      uniqueKeys: regularDict.keys, 
      values: regularDict.values
    )
    // => EITHER {key2=>value2, key1=>value1} OR {key1=>value1, key2=>value2}
    

    This will not magically sort anything though, the resulting orderedDict will have key-value entries of same random order as the regularDict. But any future changes to the order will be persistent. For example, you could order by keys of a type conforming to Comparable like this:

    orderedEntries.sort(by: { $0.key < $1.key })
    // => {key1=>value1, key2=>value2}