iOS How to Find Minimum Difference Between the values of Array of Floating/Integer Values

Viewed 984

I have an array of floating values:

let array:[Double] = [2270.87, 2285.15, 2273.49, 2312.89, 2323.07, 2336.14, 2355.09, 2633.0, 2671.34]

I need and single line logic using swift higher-order functions or array extension to find the minimum difference value from all differences between the values.

I tried but I'm unable to move further:

let array  = [2270.87, 2285.15, 2273.49, 2312.89, 2323.07, 2336.14, 2355.09, 2633.0, 2671.34]
let minDiff = array.map( { *All differences between array of values* } ).reduce(0, min)

Actually I am showing these values in a graph. So I want the minimum absolute fluctuation between the values. in the above example like 2323.07 and 2336.14 have minimum fluctuation 10.18.

3 Answers

You can zip two arrays where second one doesn't have first element. Then you can get abs value of subtraction value with index x + 1 from that with index x, and using map() you can get the minimum value from all of those absolute values.

zip(array, array.dropFirst()).map { abs($1 - $0) }.min() // 10.180000000000291

If you want to find the minimum absolute difference between two consecutive elements of your array, you can use below extension, which maps over the indices of the array, to access 2 consecutive elements at a time.

dropLast is important to ensure that we stop iteration before the last element (since we calculate the diff between the penultimate and last element before reaching the last index).

extension Array where Element: Comparable, Element: SignedNumeric {
    func minConsecutiveDiff() -> Element? {
        indices.dropLast().map { abs(self[$0] - self[$0+1])}.min()
    }
}

let array:[Double] = [2270.87, 2285.15, 2273.49, 2312.89, 2323.07, 2336.14, 2355.09, 2633.0, 2671.34]
array.minConsecutiveDiff() // 10.18

If you were interested in the diff between any two elements of the array, not just consecutive ones, you could get that by first sorting the Array and then calculating the diff between the consecutive elements of the sorted array as @MartinR pointed out in comments.

extension Array where Element: Comparable, Element: SignedNumeric {
    func minDiff() -> Element? {
        sorted().minConsecutiveDiff()
    }
}

Here is one way using forEach

var min: Double = array.max()!
var previous: Double?
array.forEach {
    if let prev = previous, min > abs($0 - prev) {
        min = abs($0 - prev)
    }
    previous = $0
}

another option is to use reduce(into:) with a tuple

let min = array.reduce(into: (Double, Double)(array.first!, 0)) {
    if abs($1 - $0.1) < $0.0 {
        $0.0 = abs($1 - $0.1)
    }
    $0.1 = $1
}.0

which both gives 10.18 as the smallest difference.

Related