将连续过滤器应用于 Ruby 中的数组
Apply successive filters to an array in Ruby
我有一些对象的数组,可能是字符串或数字。我想对这个数组应用一些任意过滤器,并且我希望能够指定过滤器的顺序。这是一个示例(我知道在这个玩具示例中,顺序无关紧要,但我希望能够为另一种情况指定):
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
现在,我知道我可以做到这一点:
odds = filter_odd(all)
filter_multiple_five(odds)
但随着我的要求发生变化,我不得不不断添加更多过滤器,这样做并不是很令人满意。我正在 Ruby.
中寻找一种简洁、实用的方法来执行此操作
好的,剧透,我找到了一个解决方案。因为我在任何地方都找不到这个确切的问题,所以我决定在这里post它:
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]
调用filters
returns正确的结果。在第一个过滤器之后,它只产生块的几率,在第二个过滤器之后它产生 returns 5 的奇数倍数:
filter(all, filters)
=> [5]
您可以使用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]
我有一些对象的数组,可能是字符串或数字。我想对这个数组应用一些任意过滤器,并且我希望能够指定过滤器的顺序。这是一个示例(我知道在这个玩具示例中,顺序无关紧要,但我希望能够为另一种情况指定):
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
现在,我知道我可以做到这一点:
odds = filter_odd(all)
filter_multiple_five(odds)
但随着我的要求发生变化,我不得不不断添加更多过滤器,这样做并不是很令人满意。我正在 Ruby.
中寻找一种简洁、实用的方法来执行此操作好的,剧透,我找到了一个解决方案。因为我在任何地方都找不到这个确切的问题,所以我决定在这里post它:
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]
调用filters
returns正确的结果。在第一个过滤器之后,它只产生块的几率,在第二个过滤器之后它产生 returns 5 的奇数倍数:
filter(all, filters)
=> [5]
您可以使用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]