是否有一种方法可以使bsearch
返回最后一次出现而不是第一次出现?
例如:
arr = [1,2,3,4,4,5]
arr.bsearch { |x| 4 - x } # this returns the first 4
hash = {
1 => {
"foo" => "bar",
"test" => "abc"
},
4 => {
"foo" => "bar2",
"test2" => "def"
},
5 => {
"test2" => "abc"
}
}
hash.keys.bsearch { |x| !hash[x]['test2'].nil? } # this returns 4, but I want it to return 5
我想找到'test'2不为空的最后一次出现。
答案 0 :(得分:0)
您可以在此处尝试使用变量 y 进行存储。
hash.keys.bsearch {| x | y = x如果!hash [x] ['test2']。nil? }
答案 1 :(得分:0)
您可以反转哈希并对其运行bsearch
。用您的哈希值:
hash.reverse_each.to_h.keys.bsearch { |x| !hash[x]['test2'].nil? }
=> 5
This post将阐明bsearch
的工作方式。
答案 2 :(得分:0)
bsearch
所使用的格式(采用产生整数的块)不会返回相同值中的第一个;它返回偶然发现的任何东西,因为它认为它们是相同的。例如:
[1, 2.1, 2.2, 2.3, 2.4, 2.5, 2.6, 2.7, 3, 4, 5].bsearch { |e| 2 - e.to_i }
# => 2.5
返回的值位于2.x
值的中间,仅仅是因为bsearch
首先偶然发现了它。如果要返回第一个值,则必须使用另一种形式,其中该块产生布尔值。从那里开始,对其进行最后的工作很简单。例如:
array = [1, 2.1, 2.2, 2.3, 2.4, 2.5, 2.6, 2.7, 3, 4, 5]
indices = array.size.times.to_a
first_index = indices.bsearch { |i| array[i].to_i >= 2 }
last_index = indices.reverse.bsearch { |i| array[i].to_i <= 2 }
array[first_index..last_index]
# => [2.1, 2.2, 2.3, 2.4, 2.5, 2.6, 2.7]
如果您不需要索引,而是第一个和最后一个元素本身,那么就足够了:
first_element = array.bsearch { |e| e.to_i >= 2 }
last_element = array.reverse.bsearch { |e| e.to_i <= 2 }
对于问题的哈希部分,您的问题很奇怪。对于其中块产生布尔值的bsearch
格式(如您在该示例中使用的那样),强制性的是,对于要搜索的元素之前的任何元素,块均产生false
,而{{1} }之后。 (类似地,当block产生整数时,它应返回负值,后跟零,后跟正值。换句话说,应该根据要搜索的谓词对数组进行排序。)因此,根据定义,最后一个元素符合您的条件(所有没有true
的元素都在所有带有"test1"
的元素之前)必须为"test1"
。