我的应用程序中有一个查询对象,它使用 Array#select 方法过滤数据
class QueryObject
def call(filters)
data = get_data # returns array
data = by_param1(data, filter[:param1])
data = by_param2(data, filter[:param2])
end
private
def by_param1(data, filter)
data.select { |d| #filtering goes here }
end
def by_param2(data, filter)
data.select { |d| #filtering goes here }
end
end
如何将过滤块传递给 Enumerable 以应用所有过滤器并将它们链接起来?
我知道我可以做这样的事情:
data.select { |d| by_param1 && by_param2 }
但对我来说这并不优雅,因为我有很多过滤器
你可以在这里使用#reduce来达到很好的效果。
例如,
filter_1 = -> (thing) { thing > 2 }
filter_2 = -> (thing) { thing < 5 }
def better_filter(input)
input * 7 < 23
end
filters = [filter_1, filter_2, method(:better_filter), :positive?]
array = (0..9).to_a
filters.reduce(array) { |result, filter| result.select(&filter) }
# [3]
就您的问题而言,可能是这样的:
class QueryObject
def call(filters)
data = get_data # returns array
filters.reduce(data) { |result, filter| result.select(&filter) }
end
end
这假设
filters
作为响应 #call
的对象数组传入。这可以是一个 lambda、一个简单的 ruby 类,甚至是一个符号,如我在示例中所示。