在 Ruby 中应用多个过滤器的最优雅方式#select

问题描述 投票:0回答:1

我的应用程序中有一个查询对象,它使用 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 }

但对我来说这并不优雅,因为我有很多过滤器

ruby block enumerator
1个回答
0
投票

你可以在这里使用#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 类,甚至是一个符号,如我在示例中所示。

© www.soinside.com 2019 - 2024. All rights reserved.