我不明白为什么当数组有2个值时bsearch方法返回nil.
arr = [1, 2]
arr.bsearch { |el| el < 2 }
我不明白为什么当数组有2个值时bsearch方法返回nil.
arr = [1, 2]
arr.bsearch { |el| el < 2 }
100 doc
您只需要仔细阅读Array#bsearch份文档即可.它指出bsearch
有两种形式或模式:"find-minimum模式和find-any mode.在任何一种情况下,数组的元素都必须相对于块是单调的(或排序的)."对于find-minimum模式,块返回true
或false
;对于find-any模式,块返回与数组元素相同的类值.因此,您正在使用查找最小值模式.
同样来自文档,在find-minimum模式下"必须有一个索引i, 0 <= i <= ary.size
,以便:
i
的任何元素,块返回false
;并且i
的任何元素,该块返回true
.此方法返回第i个元素.如果i
等于ary.size
,则返回零."
Examining your code
现在让我们判断一下您的声明,稍微修改一下:
arr = [1, 2, 3]
arr.bsearch { |el| el < 2 } #=> nil
我们希望找到满足使用bsearch
所施加的要求的指数0
、1
或2
.
假设兴趣指数是0
.由于没有小于零的指数,因此我们测试arr[1] < 2
和arr[2] < 2
(2 < 2
和3 < 2
)是否都是true
.事实上两者都是false
.因此,指数0
不再考虑.
现在假设文档中提到的指数是1
.我们要求arr[0] < 2
是false
,但它是true
.因此我们可以排除指数1
.
为了使指数等于2
,我们要求arr[0] < 2
和arr[1] < 2
都是false
,但实际上都是true
.
由于没有满足使用besearch
要求的索引,因此返回nil
.
Correcting your code
显然,对于arr = [1, 2, 3]
,该表达必须写如下.
arr.bsearch { |el| el >= 2 } #=> 2
arr.bsearch { |el| el > 2 } #=> 3
arr.bsearch { |el| el > 0 } #=> 1
arr.bsearch { |el| el > 3 } #=> nil
Other examples
以下是数组包含integer的更多示例.
ary = [2, 4, 6]
ary.bsearch { |el| el > -99 } #=> 2
ary.bsearch { |el| el > 1 } #=> 2
ary.bsearch { |el| el > 2 } #=> 4
ary.bsearch { |el| el >= 2 } #=> 2
ary.bsearch { |el| el >= 6 } #=> 6
ary.bsearch { |el| el > 6 } #=> nil
The array can be non-increasing
请注意,数组不需要是非递减的,只需monotone,这意味着非递减或非递减.这是一个例子,其中数组是非增的(实际上是严格减的).区块计算当然必须进行相应调整.
ary = [6, 4, 2]
ary.bsearch { |el| el <= 7 } #=> 6
ary.bsearch { |el| el <= 99} #=> 6
ary.bsearch { |el| el < 5 } #=> 4
ary.bsearch { |el| el <= 4 } #=> 4
ary.bsearch { |el| el < 4 } #=> 2
ary.bsearch { |el| el <= 2 } #=> 2
ary.bsearch { |el| el < 2 } #=> nil
ary.bsearch { |el| el <= 1 } #=> nil
The array may contain non-numeric values
唯一的要求是成对的元素可以与飞船操作员<=>
进行比较.如果a < b
,a <=> b
返回-1
,如果a == b
,则返回0
,如果a > b
,则返回1
.
例如,在字符串的情况下,String#<=>被bsearch
使用.以下是一些例子.
ary = ['brush', 'keep', 'task']
ary.bsearch { |s| s >= 'hi' } #=> "keep"
ary.bsearch { |s| s >= 'align' } #=> "brush"
ary.bsearch { |s| s >= 'mama' } #=> "task"
ary.bsearch { |s| s >= 'tar' } #=> "task"
ary.bsearch { |s| s >= 'tax' } #=> "nil"