我有一些对象的数组,可能是字符串或数字。我想对这个数组应用一些任意的过滤器,我希望能够指定过滤器的顺序。这是一个例子(我知道在这个玩具示例中,顺序并不重要,但我希望能够为另一个案例指定):
Embedded
现在,我知道我可以这样做:
filters = [:filter_odd, :filter_multiple_five]
all = (1..10).to_a #[1, 2, ... 10]
filter(all, filters)
# should return [5]
# where, i.e.:
private
def filter_odd(numbers)
numbers.select(&:odd?)
end
def filter_multiple_five(numbers)
numbers.select { |number| number%5 == 0 }
end
但随着我的要求发生变化,我不得不添加更多过滤器,这样做并不是很令人满意。我在Ruby中寻找一种干净,实用的方法。
答案 0 :(得分:2)
好的,扰流板,我找到了一个解决方案。由于我无法在任何地方找到这个确切的问题,我决定在这里发布:
odds = filter_odd(all)
filter_multiple_five(odds)
所以,如果你有一些过滤方法:
def filter(array_of_numbers, filters)
filters.inject(array_of_numbers) do |remaining_numbers, filter|
send(filter, remaining_numbers)
end
end
过滤方法名称列表(作为符号)和一些数据:
private
def filter_odd(numbers)
numbers.select(&:odd?)
end
def filter_multiple_five(numbers)
numbers.select { |number| number%5 == 0 }
end
调用filters = [:filter_odd, :filter_multiple_five]
all = (1..10).to_a #[1, 2, ... 10]
会返回正确的结果。在第一个过滤器之后,它只产生块的几率,在第二个过滤器之后它返回奇数倍的5:
filters
答案 1 :(得分:2)
您可以使用blocks
,这是一种灵活的方式。如果您不熟悉块,可以将其用作参考:understanding-ruby-blocks-procs-and-lambdas
class Array
def filter
self.select{ |e| yield(e)} if block_given?
end
end
arr = (1..10).to_a
puts arr.filter{ |n| n % 5 == 0 }.inspect
puts arr.filter{ |n| n.odd? }.inspect
puts arr.filter{ |n| n % 3 == 0 }.inspect
输出:
[5, 10]
[1, 3, 5, 7, 9]
[3, 6, 9]