Last active
December 28, 2019 22:23
-
-
Save pofat/b9e105da22eac6d096f5d02cffe91b67 to your computer and use it in GitHub Desktop.
String KeyPath accessor of Dictionary
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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