作者热门文章
- xml - AJAX/Jquery XML 解析
- 具有多重继承的 XML 模式
- .net - 枚举序列化 Json 与 XML
- XML 简单类型、简单内容、复杂类型、复杂内容
在 ruby 中我们可以这样做:
stuff_in_trash.detect(&:eatable?)
=> :pack_of_peanuts
stuff_in_trash.detect(&:drinkable?)
=> nil
但是,如果我们对 block 第一次为真时的值感兴趣,而不是 block 为其取真值的第一个项目感兴趣怎么办?
也就是转换如下代码:
def try_to_make_artwork_from(enumerable)
enumerable.each do |item|
result = make_artwork_from item
return result if result
end
nil
end
类似于:
def try_to_make_artwork_from(enumerable)
enumerable.try_with { |item| make_artwork_from item }
end
初始代码中需要的是:
nil
;make_artwork_from
(我们可以说它不能保证在您下次调用时返回相同的结果)。不太理想的是,使用了三次result
,但它与故事无关。
编辑:抱歉,最初的实现是不正确的,它需要返回 nil
以防 block 值永远不为真。
enumerable.lazy.map(&:block).detect(&:itself)
完成这项工作,但这是最简单的方法吗?与简单地使用 each
并缓存值相比,它是否有效?
最佳答案
it does the job, but is the simplest way? Is it efficient compare to simply using a each and caching the value?
我们可以定义这个方法:
def first_truthy_block(enumerable, &block)
enumerable.lazy.map(&block).find(&:itself)
end
实际操作:
array = [0,1,2,3,4,:x5,'abc']
puts first_truthy_block(array) { |x|
if x ** 2 > 10 then
"ARTWORK with #{x}!!!"
end
}
#=> ARTWORK with 4!!!
可以更简单吗?
enumerable
是必需的,它是您正在处理的对象。lazy
,它不会尽快停止,并会抛出 :x5**2
的异常。使用标准的 Enumerable
方法,我看不出它还能更简单。
它比您的 each
方法慢。它基本上做同样的事情,应该具有相同的复杂性,但它确实使用了更多的方法调用并创建了更多的对象:
require 'fruity'
def first_truthy_block_lazy(enumerable, &block)
enumerable.lazy.map(&block).find(&:itself)
end
def first_truthy_block_each(enumerable, &block)
enumerable.each do |item|
result = block.call(item)
return result if result
end
nil
end
big_array = Array.new(10_000){rand(4)} + [5] + Array.new(10_000){rand(20)} + [:x, :y, 'z']
compare do
_lazy_map do
first_truthy_block_lazy(big_array) { |x|
if x ** 2 > 10 then
"ARTWORK with #{x}!!!"
end
}
end
_each do
first_truthy_block_each(big_array) { |x|
if x ** 2 > 10 then
"ARTWORK with #{x}!!!"
end
}
end
end
果味返回:
Running each test once. Test will take about 1 second.
_each is faster than _lazy_map by 3x ± 0.1
关于 ruby 可枚举 : first truthy value of a block,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41571054/
我是一名优秀的程序员,十分优秀!