Skip to content

Instantly share code, notes, and snippets.

@pofat
Last active December 28, 2019 22:23
Show Gist options
  • Save pofat/b9e105da22eac6d096f5d02cffe91b67 to your computer and use it in GitHub Desktop.
Save pofat/b9e105da22eac6d096f5d02cffe91b67 to your computer and use it in GitHub Desktop.
String KeyPath accessor of Dictionary
import Foundation
// Time Complexity: O(N), N stands for the level of key path
extension Dictionary where Key == String {
subscript(keyPath keyPath: String) -> Any? {
get {
guard !keyPath.isEmpty else { return nil }
var value: Any? = self
for key in keyPath.components(separatedBy: ".") {
if let node = (result as? [Key: Any])?[key] {
value = node
} else {
return nil
}
}
return value
}
set {
let paths = keyPath.components(separatedBy: ".")
guard let first = paths.first else {
return
}
if paths.count == 1, let newValue = newValue as? Value {
self[first] = newValue
return
}
if var nestedDict = self[first] as? [Key: Any] {
nestedDict[keyPath: Array(paths.dropFirst()).joined(separator: ".")] = newValue
self[first] = nestedDict as? Value
}
}
}
}
extension Dictionary where Key == String {
subscript(string keyPath: String) -> String? {
get { return self[keyPath: keyPath] as? String }
set { self[keyPath: keyPath] = newValue }
}
subscript(integer keyPath: String) -> Int? {
get { return self[keyPath: keyPath] as? Int }
set { self[keyPath: keyPath] = newValue }
}
}
// Example
var dict: [String: Any] = [
"batchcomplete": "",
"continue": [
"rncontinue": "0.067678657404|0.067678667039|13394072|0",
"continue": "-||"
],
"query": [
"random": [
"id": 34538560,
"ns": 3,
"title": "User talk:59.188.42.121"
]
]
]
dict[keyPath: "query.random.id"] // 34538560, Any?
dict[keyPath: "query.random.title"] // "User talk:59.188.42.121"
dict[string: "query.random.title"]?.append("GG") // // "User talk:59.188.42.121GG"
dict[keyPath: "query.random.id"] = 12345
dict[integer: "query.random.id"] // 12345
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment