从数组中选择最接近的NSNumber

Pau*_*len 1 objective-c nsnumber nsarray

我有一堆NSNumbers 的数组.从UISlider用户停止拖动时获取某个值.我想从数组中获取关闭数字.

因此,例如,如果用户拖动UISlider13,并且NSArray包含NSNumberswith 1015; 我想15从阵列中获取.

数组示例:

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];
Run Code Online (Sandbox Code Playgroud)

如何从阵列中获取正确的数字?

rob*_*off 12

在您的帖子中,数组已排序.如果它总是排序,您可以使用二进制搜索. NSArray有一个方便的方法:

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];
    }];
Run Code Online (Sandbox Code Playgroud)

现在有四种可能性:

  1. 每个元素values都大于targetNumber:index为零.
  2. 每个元素values都小于targetNumber:indexvalues.count.
  3. valuescontains targetNumber:indextargetNumberin 的索引values.
  4. index是最大元素的索引values大于targetNumber.

我已按照我们处理它们的顺序巧妙地列出了这些案例.这是案例1:

if (index == 0) {
    return [values[0] floatValue];
}
Run Code Online (Sandbox Code Playgroud)

案例2:

if (index == values.count) {
    return [[values lastObject] floatValue];
}
Run Code Online (Sandbox Code Playgroud)

我们可以一起处理案例3和4:

CGFloat leftDifference = targetNumber - [values[index - 1] floatValue];
CGFloat rightDifference = [values[index] floatValue] - targetNumber;
if (leftDifference < rightDifference) {
    --index;
}
return [values[index] floatValue];
Run Code Online (Sandbox Code Playgroud)