Skip to content

Instantly share code, notes, and snippets.

@harrytwright
Last active May 16, 2022 16:01
Show Gist options
  • Save harrytwright/dfab0fbd96a582002b10e3336eb4bbe6 to your computer and use it in GitHub Desktop.
Save harrytwright/dfab0fbd96a582002b10e3336eb4bbe6 to your computer and use it in GitHub Desktop.
Very basic implementaion of `lodash.get`. Not meant for production, just a proof
protocol KeyValuePathing {
subscript(keyPathWithString keyPath: String) -> Any? { get }
}
extension Array: KeyValuePathing {
subscript(keyPathWithString keyPath: String) -> Any? {
get {
var parts = keyPath.components(separatedBy: ".")
let initialKey = parts.removeFirst()
guard let index = Int(initialKey), self.count - 1 > index else {
return nil
}
if let value = self[index] as? KeyValuePathing {
return value[keyPathWithString: parts.joined(separator: ".")]
}
return self[index]
}
}
}
extension Dictionary: KeyValuePathing {
private func _defaultKeyPath(keyPath: Key) -> Any? {
return self[keyPath]
}
subscript(keyPathWithString keyPath: String) -> Any? {
get {
var parts = keyPath.components(separatedBy: ".")
let initialKey = parts.removeFirst()
if let value = self._defaultKeyPath(keyPath: initialKey as! Key) as? KeyValuePathing {
return value[keyPathWithString: parts.joined(separator: ".")]
} else if let key = initialKey as? Key, let value = self._defaultKeyPath(keyPath: key) {
return value
}
return nil
}
}
}
func get<Key: Hashable, Value>(_ keyPath: String, in object: Dictionary<Key, Value>, withDefaultValue defaultValue: Any? = nil) -> Any? {
return object[keyPathWithString: keyPath] ?? defaultValue ?? nil
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment