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.
相关问题
- How to toggle on Order in ReactJS
- PHP Recursively File Folder Scan Sorted by Modific
- How to get the maximum of more than 2 numbers in V
- “Zero out” sensitive String data in Swift
- Faster loop: foreach vs some (performance of jsper
相关文章
- Numpy matrix of coordinates
- Using if let syntax in switch statement
- Enum with associated value conforming to CaseItera
- Sort TreeView Automatically Upon Adding Nodes
- Swift - hide pickerView after value selected
- Is there a Github markdown language identifier for
- PHP: Can an array have an array as a key in a key-
- How can I vertically align my status bar item text
Loop through the values in your array, calculate the abs() difference, compare it to a running 'currentSmallestDifference' variable, if the current difference is smaller than that then overwrite it with the new value, at the same time keep a record of the array index...
This solves it in O(n).
But if the array was already sorted (O(nlog(n)), you could then do a O(log(n)) binary search for X in the array and find the closest value to it. No need to use abs() at all in that case... just comparisons
But for array sizes 1 to 7, algorithmic complexity isn't really a factor.
In fact for array size 1, the question isn't even a factor (?!?)
Update>> Just realised the title said smallest positive difference.. So just ditch all the abs() stuff and make sure (array(i) - X) is in the correct sign/direction.
Here is a method that does a single loop that calculates the closest positive value. Not a one-liner. But still effective
Wrapped this into an extension:
In Swift 2 you can do it as a "one-liner" with functional-style programming:
enumerate()
iterates over all array elements together with the corresponding index, andminElement()
returns the "smallest"(index, element)
pair with respect to the closure. The closure compares the absolute values of the difference of two elements tox
.(It is assumed here that the array is not empty, so that
minElement()
does not returnnil
.)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.
Swift 3:
The Swift 1.2 version can be found in the edit history.
Another alternative would be to use the
reduce
methodIf you want to avoid repeated calculation of the absolutes, you could first map every array element to it's absolute difference from the input number and then find the minimum.
Swift 4.2
Not exactly what the OP is asking, but you can use the
first(where:)
andfirstIndex(where:)
array methods on a sorted array to get the first value greater than x: