chronos chronos - 18 days ago 5
Swift Question

how to find/filter the array element with the smallest positive difference

Using Swift, I am trying to workout a complex array filter or sort and I am stuck. My array of integers can contain between 1 and 7 elements. Given a certain integer value (say X) which is not in the array, I would like to find the array element that gives the smallest difference between itself and X.

Answer

In Swift 2 you can do it as a "one-liner" with functional-style programming:

let numbers = [ 1, 3, 7, 11]
let x = 6

let closest = numbers.enumerate().minElement( { abs($0.1 - x) < abs($1.1 - x)} )!

print(closest.element) // 7 = the closest element
print(closest.index)   // 2 = index of the closest element

enumerate() iterates over all array elements together with the corresponding index, and minElement() returns the "smallest" (index, element) pair with respect to the closure. The closure compares the absolute values of the difference of two elements to x.

Note that this is probably not the fastest solution for large arrays, because the absolute differences are computed twice for (almost) all array elements. But for small arrays this should not matter.

It is not as elegant in Swift 1.2. There is no minElement() function which takes an comparison closure as an argument, and many tasks can only be done with global functions instead of (protocol extension) methods. Here is one possible solution, this is quite similar to what @hennes suggested in his answer, translated to Swift 1.2:

let closest = reduce(enumerate(numbers), (index: -1, element: Int.max), { abs($0.1 - x) < abs($1.1 - x) ? $0 : $1 } )
println(closest.element) // 7
println(closest.index)   // 2

Swift 3:

let numbers = [ 1, 3, 7, 11]
let x = 6
let closest = numbers.enumerated().min( by: { abs($0.1 - x) < abs($1.1 - x))
print(closest.element) // 7
print(closest.offset) // 2
Comments