Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Kotlin "takeIf" statement equivalent in swift?

Tags:

swift

I have this code very simple in kotlin which returns a value if a certain condition is satisfied, or null

val speed = location.speed.takeIf { it>=0 }

I'm trying to do the same in swift, but the only way I found is this:

let speed:Double?
if (location.speed>=0){
    speed = location.speed
}else{
    speed = nil
}

Is there any way more elegant?

like image 928
Corbella Avatar asked Oct 14 '22 22:10

Corbella


1 Answers

There isn't something like that in Swift, so we need to find a way to write a takeIf function ourselves.

In Kotlin, takeIf is available on everything, as an extension function on all T:

inline fun <T> T.takeIf(predicate: (T) -> Boolean): T?

In Swift, you can't write an extension on Any, so we can only make a global function:

func take<T>(_ value: T, if predicate: (T) throws -> Bool) rethrows -> T? {
    try predicate(value) ? value : nil
}

// example usage:
let x = Int.random(in: 0..<10)
let y = take(x, if: { $0 > 5 })

If you are creative enough to think of an operator, you can turn this into an infix operator, similar to how the Kotlin takeIf is in between the receiver and the predicate.

// I am not creative enough...
infix operator ???

func ???<T>(value: T, predicate: (T) throws -> Bool) rethrows -> T? {
    try predicate(value) ? value : nil
}

let a = Int.random(in: 0..<10)
let b = x ??? { $0 > 5 }
like image 133
Sweeper Avatar answered Oct 20 '22 17:10

Sweeper