Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save DominatorVbN/99291c0f1868572241673aefa63aa25b to your computer and use it in GitHub Desktop.
Save DominatorVbN/99291c0f1868572241673aefa63aa25b to your computer and use it in GitHub Desktop.
Utility function that decodes a dictionary in place of array
extension KeyedDecodingContainer {
/// Decodes a dictionary in place of array
/// - Parameters:
/// - type: Type of the element of array should be decodable
/// - key: The key against which the array is present in the container
/// - keyPath: key path on the element type to be the key of dictionay
/// - Returns: return the dictionary
func decodeArrayAsDictionary<T: Decodable, Key: Hashable>(
_ type: Dictionary<Key,T>.Type,
forKey key: KeyedDecodingContainer<K>.Key,
withKeyPath keyPath: KeyPath<T, Key>
) throws -> Dictionary<Key,T> {
var arrayContainer = try self.nestedUnkeyedContainer(forKey: key)
var map = Dictionary<Key,T>()
if let count = arrayContainer.count {
// Considering there is less likely duplicate element, adding this to improve the performance as not reserving the count may result in multiple reallocations.
map.reserveCapacity(count)
}
while !arrayContainer.isAtEnd {
// Decode the next LitmusExperiment, this makes the nested unkeyed container move to the next element in it, thus when we exhaust all the element `UnkeyedDecodingContainer.getter:isAtEnd` would be true and we will break out of this loop
let arrayElement = try arrayContainer.decode(T.self)
let key = arrayElement[keyPath: keyPath]
map[key] = arrayElement
}
return map
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment