I have an array with a bunch of NSNumber
s. From an UISlider
I get a certain value when the user stops dragging it. I would like to get the closes number from the array.
So for instance, if the user drags the UISlider
to 13
, and the NSArray
contains the NSNumbers
with 10
and 15
; I want to get 15
from the array.
Example of array:
NSArray *values = [NSArray arrayWithObjects:[NSNumber numberWithInt:15],
[NSNumber numberWithInt:20],
[NSNumber numberWithInt:30],
[NSNumber numberWithInt:45],
[NSNumber numberWithInt:60],
[NSNumber numberWithInt:90],
[NSNumber numberWithInt:110], nil];
How do I get the correct number from the array?
In your post, the array is sorted. If it's always sorted, you can use binary search. NSArray
has a convenient method for that:
CGFloat targetNumber = mySlider.value;
NSUInteger index = [values indexOfObject:@(targetNumber)
inSortedRange:NSMakeRange(0, values.count)
options:NSBinarySearchingFirstEqual | NSBinarySearchingInsertionIndex
usingComparator:^(id a, id b) {
return [a compare:b];
}];
Now there are four possibilities:
- Every element of
values
is larger thantargetNumber
:index
is zero. - Every element of
values
is smaller thantargetNumber
:index
isvalues.count
. values
containstargetNumber
:index
is the index oftargetNumber
invalues
.index
is the index of the smallest element ofvalues
that is greater thantargetNumber
.
I've cleverly listed the cases in the order we'll handle them. Here's case 1:
if (index == 0) {
return [values[0] floatValue];
}
Here's case 2:
if (index == values.count) {
return [[values lastObject] floatValue];
}
We can handle cases 3 and 4 together:
CGFloat leftDifference = targetNumber - [values[index - 1] floatValue];
CGFloat rightDifference = [values[index] floatValue] - targetNumber;
if (leftDifference < rightDifference) {
--index;
}
return [values[index] floatValue];
If your values
array is in order and you always want the value just larger than (or equal to) the entered value you could do something like this:
NSInteger count = 0;
do {
count++;
} while (enteredNum > [values[count] intValue]);
// Do something with [values[count] intValue]
来源:https://stackoverflow.com/questions/14086770/pick-closest-nsnumber-from-array