Skip to content

Instantly share code, notes, and snippets.

@oaleeapp
Forked from loganwright/Dictionary+KeyPaths.swift
Last active June 4, 2019 08:35
Show Gist options
  • Save oaleeapp/52590eb91b6e8288ff1ebcc7380f7193 to your computer and use it in GitHub Desktop.
Save oaleeapp/52590eb91b6e8288ff1ebcc7380f7193 to your computer and use it in GitHub Desktop.
Dictionary+KeyPaths
import Foundation
extension Dictionary {
mutating public func setValue(value: Any, forKeyPath keyPath: String) {
var keys = keyPath.components(separatedBy: ".")
guard let first = keys.first as? Key else { print("Unable to use string as key on type: \(Key.self)"); return }
keys.remove(at: 0)
if keys.isEmpty, let settable = value as? Value {
self[first] = settable
} else {
let rejoined = keys.joined(separator: ".")
var subdict: [NSObject : AnyObject] = [:]
if let sub = self[first] as? [NSObject : AnyObject] {
subdict = sub
}
subdict.setValue(value: value, forKeyPath: rejoined)
if let settable = subdict as? Value {
self[first] = settable
} else {
print("Unable to set value: \(subdict) to dictionary of type: \(type(of: self))")
}
}
}
public func valueForKeyPath<T>(keyPath: String) -> T? {
var keys = keyPath.components(separatedBy: ".")
guard let first = keys.first as? Key else { print("Unable to use string as key on type: \(Key.self)"); return nil }
guard let value = self[first] else { return nil }
keys.remove(at: 0)
if !keys.isEmpty, let subDict = value as? [NSObject : AnyObject] {
let rejoined = keys.joined(separator: ".")
return subDict.valueForKeyPath(keyPath: rejoined)
}
return value as? T
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment