Swift KeyPath is awesome

guard let name = nameField.text?.trimmingCharacters(in: .whitespaces), name.isUserName else {    nameField.becomeFirstResponder()
}
guard let email = emailField.text?.trimmingCharacters(in: .whitespaces), email.isEmail else { emailField.becomeFirstResponder()
}
guard let password = passwordField.text?.trimmingCharacters(in: .whitespaces), password.isPassword else { passwordField.becomeFirstResponder()
}
public protocol KPValidation {}extension KPValidation {

public func validate(_ rules: ((Self) -> Bool)...) -> Bool {

for rule in rules where !rule(self) {
return false
}

return true
}
}
extension Model: KPValidation {}
let user = viewModel.modelguard user.validate(
\.email.isSome,
\.email!.isEmpty.not,
\.email!.isEmail,
{ $0.email.hasSuffix("@gmail.com") }) else {
emailField.becomeFirstResponder()
return
}
public extension Optional {

var isSome: Bool {
return self != nil
}
}
public extension Bool {

var not: Bool {
return !self
}
}
public extension Int {

var largerThan5: Bool {
return self > 5
}
}
\String.first?.isNumber\DateComponents.isValidDate\[Int].isEmpty

An operator is a special symbol or phrase that you use to check, change, or combine values. For example, the addition operator (+) adds two numbers, as in let i = 1 + 2, and the logical AND operator (&&) combines two Boolean values, as in if enteredDoorCode && passedRetinaScan.

extension KeyPath where Value: AdditiveArithmetic {

public static func + (_ lhs: KeyPath, _ rhs: Value) -> (Root) -> (Value) {
{ $0[keyPath: lhs] + rhs }
}

...
}
public func + <Root, Value: AdditiveArithmetic> (_ lhs: @escaping (Root) -> Value, _ rhs: @escaping (Root) -> Value) -> (Root) -> (Value) { { lhs($0) + rhs($0) }}
let closure1: (User) -> Bool = \User.password.count >= 8let closure2: (User) -> Bool = \User.password.count <= 20let closure3: (User) -> Bool = closure1 && closure2
let closure4: (User) -> Int = \User.followingCount + 1
let closure5: (User) -> Int = (\User.int1 + 12) * (\User.int2 - 68)
extension Sequence {    public func sorted<Value: Comparable>(by keyPath: KeyPath<Element, Value>) -> [Element] {        return self.sorted(by: { $0[keyPath: keyPath] < $1[keyPath: keyPath] })
}
}
let users = [user1, user2, user3]let sorted = users.sorted(by: \User.followers.count)
users.filter(\.isAdmin)
.first(\.followers.count < 5 )
.sorted(by: \.followers.count)
.compactMap(\.followers.first)

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store