首页 > 解决方案 > 将数组元素减少为嵌套类实例化

问题描述

鉴于我有以下数组:

operations = [
  [
    :do_this,
    ["a"]
  ],
  [
    :do_that,
    ["b", "c"]
  ],
  [
    :then_this,
    ["b"]
  ]
]

我如何在上面进行转换,使其看起来像:

DoThisOperation.new(DoThatOperation.new(ThenThisOperation.new('b'), 'b' , 'c'), 'a')

这是据我所知:

require 'active_support/inflector'

class DoThisOperation
  def initialize(successor = nil, a)
  end
end

class DoThatOperation
  def initialize(successor = nil, b, c)
  end
end

class ThenThisOperation
  def initialize(successor = nil, b)
  end
end

operations = [
  [
    :do_this,
    ["a"]
  ],x
  [
    :do_that,
    ["b", "c"]
  ],
  [
    :then_this,
    ["b"]
  ]
]

operations.reverse.reduce do |result, element|
  klass_name = element[0].to_s.camelize
  args = element[1]
  "#{klass_name}Operation".constantize.new(result, *args)
end

减少/注入是解决这个问题的正确方法吗?如果是这样,我应该在上面做什么?

标签: ruby-on-railsruby

解决方案


减少/注入是解决这个问题的正确方法吗?

是的,但您需要将初始值传递给reduce,例如nil。否则,第一个元素(在您的情况下为最后一个元素)将用作初始值而不进行转换。

这会起作用:

operations.reverse.reduce(nil) do |result, element|
  klass_name = element[0].to_s.camelize
  args = element[1]
  "#{klass_name}Operation".constantize.new(result, *args)
end

您可以使用数组分解进一步简化它:

operations.reverse.reduce(nil) do |result, (name, args)|
  klass_name = name.to_s.camelize
  "#{klass_name}Operation".constantize.new(result, *args)
end

甚至:

operations.reverse.reduce(nil) do |result, (name, args)|
  "#{name}_operation".camelize.constantize.new(result, *args)
end

推荐阅读