Skip to content

Instantly share code, notes, and snippets.

@loromits
Created October 30, 2019 09:19
Show Gist options
  • Save loromits/8805bd937ce5bc9fa2bb38b8a7c0a6ff to your computer and use it in GitHub Desktop.
Save loromits/8805bd937ce5bc9fa2bb38b8a7c0a6ff to your computer and use it in GitHub Desktop.
Change value in nested json dictionary
extension Dictionary where Key == String, Value == Any {
@dynamicMemberLookup
struct LookupPath {
fileprivate let path: [String]
subscript(dynamicMember member: String) -> LookupPath {
LookupPath(path: path + [member])
}
}
private mutating func _set(value: Any, path: [String]) throws {
switch (path.first, path.dropFirst()) {
case let (key?, []):
self[key] = value
case let (key?, rest):
var sub = (self[key] as? [Key: Any]) ?? [:]
try sub._set(value: value, path: Array(rest))
self[key] = sub
default:
return
}
}
mutating func set(value: Any, forPath path: KeyPath<LookupPath, LookupPath>) throws {
try _set(value: value, path: LookupPath(path: [])[keyPath: path].path)
}
}
// Example
var dictionary: [String: Any] = ["json": ["type": "order",
"details": ["size": 5,
"additional": ["here": 1234]]]]
dictionary.set(value: true, forPath: \.json.details.additional.here)
// ["json": ["type": "order", "details": ["size": 5, "additional": ["here": true]]]]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment