在 Ruby 中将数组操作组合在一起



我想按特定顺序对数组执行多个操作。每个行为单元都有自己的方法,我有这样的东西:

def build_array_of_cool_employees
  employees = fetch_all_employees
  employees = remove_strange_employees_from employees
  employees = add_ideal_employee_to employees
  employees = sort_by_awesomeness employees
end

我想知道是否有更好的方法。我觉得我缺少一些可以使我的代码更好的功能。是我吗?

您可以使用可链接的方法创建一个单独的类。像这样:

class EmployeeBuilder
  attr_reader :employees
  def initialize
    @employees = []
  end
  def fetch_all
    @employees.push(:qux, :baz, :bar)
    self
  end
  def remove_strange
    @employees.delete(:qux)
    self
  end
  def add_ideal
    @employees.push(:foo)
    self
  end
  def sort
    @employees.reverse!
    self
  end
end

并像这样称呼它:

def build_array_of_cool_employees
  builder = EmployeeBuilder.new
  builder.fetch_all.remove_strange.add_ideal.sort.employees
end
build_array_of_cool_employees
#=> [:foo, :bar, :baz]

在您的情况下,您应该使用方法链接。如果您不想污染Array类,则可以Array子类。

class Employees < Array
  def self.cool
    fetch_all
    .remove_strange
    .add_ideal
    .sort_by_awesomeness
  end
  def self.fetch_all
    new(...)
  end
  def remove_strange
    ...
    self
  end
  def add_ideal
    ...
    self
  end
  def sort_by_awesomeness
    ...
    self
  end
end
Employees.cool # => ...
根据

您对方法链接的感觉,这可能读起来稍微好一点,但需要扩展array,然后您可以按照您认为合适的方式直接在数组上调用自定义方法。更好的办法是让员工列出对象,然后对其进行操作,但想法是相似的。

class Array
    def sort_by_awesomeness
        #your sort
    end
    def  add_ideal_employee(cool_employee)
        self.push(cool_employee)
    end 
    def remove_strange_employees(uncool_employees)
        uncool_employees.each do |uncool_employee|
            self.delete(uncool_employee)
        end 
        # return self here to continue the method chaining
        return self
    end
end
def build_array_of_cool_employees
  employees = fetch_all_employees.add_ideal_employee(cool_employee).remove_strange_employees(uncool_employees).sort_by_awesomeness
end

这取决于您的方法是如何实现的。如果他们修改了原始数组,您可以执行以下操作:

fetch_all_employees.tap do |employees|
  remove_strange_employees_from(employees)
  add_ideal_employee_to(employees)
  sort_by_awesomeness(employees)
end

请注意,像 delete_ifpush 这样的方法会修改原始数组,所以如果你在方法的实现中使用它们,它应该可以正常工作。

最新更新