Ruby 如何调用数组中给定的不同方法

Ruby 如何调用数组中给定的不同方法,ruby,arrays,map,Ruby,Arrays,Map,特别是在使用结构时,最好能够为数组中的每个元素调用不同的方法,如下所示: array = %w{name 4 tag 0.343} array.convert(:to_s, :to_i, :to_sym, :to_f) # => ["name", 4, :tag, 0.343] 有没有简单的单行程序、ActiveSupport方法等可以轻松做到这一点?我提出的方法包括创建一个新的Struct子类,我称之为CastingStruct: class CastingStruct < St

特别是在使用结构时,最好能够为数组中的每个元素调用不同的方法,如下所示:

array = %w{name 4 tag 0.343}
array.convert(:to_s, :to_i, :to_sym, :to_f)
# => ["name", 4, :tag, 0.343]

有没有简单的单行程序、ActiveSupport方法等可以轻松做到这一点?

我提出的方法包括创建一个新的
Struct
子类,我称之为
CastingStruct

class CastingStruct < Struct
  def self.new(hash, &blk)
    super(*hash.keys) do
      define_method :initialize do |*args|
        super *hash.values.map {|method| args.shift.public_send method }
      end
      class_eval(&blk) if blk
    end
  end   
end
我会这样做:

class Array
  def convert(*args) map { |s| s.public_send args.shift } end
end    

array = %w{name 4 tag 0.343}
args = [:to_s, :to_i, :to_sym, :to_f]
array.convert(*args)
  #=> ["name", 4, :tag, 0.343]
args
  #=> [:to_s, :to_i, :to_sym, :to_f]
我加入了最后一行,显示
convert
使
args
保持不变,即使
args
convert
中被清空。这是因为
args
在被传递到
convert
之前被飞溅

根据@Arup的要求,我已经对他和我的解决方案进行了基准测试:

class Array
  def sq_convert(*args)
    zip(args).map { |string, meth| string.public_send(meth) }
  end
  def lf_convert(*args)
    map { |s| s.public_send args.shift }
  end
end    

require 'benchmark'

n = 1_000_000
array = %w{name 4 tag 0.343}
args = [:to_s, :to_i, :to_sym, :to_f]

Benchmark.bmbm(15) do |x|
  x.report("Arup's super-quick   :") { n.times { array.sq_convert(*args) } }
  x.report("Cary's lightning-fast:") { n.times { array.lf_convert(*args) } }
end

# Rehearsal ----------------------------------------------------------
# Arup's super-quick   :   2.910000   0.000000   2.910000 (  2.922525)
# Cary's lightning-fast:   2.150000   0.010000   2.160000 (  2.155886)
# ------------------------------------------------- total: 5.070000sec

#                             user     system      total        real
# Arup's super-quick   :   2.780000   0.000000   2.780000 (  2.784528)
# Cary's lightning-fast:   2.090000   0.010000   2.100000 (  2.099337)

Nit:The&:与对每个元素调用方法无关。。这就是使用&:结果的HoF函数。你能通过比较我的和你的来设定基准吗?我只是想看看破坏是否比构造快。使用splat也会使语法更直观,例如
array.convert:to_s,:to_i,:to_sym,:to_f
我在写这篇文章时使用了一些Arup Rakshit和Cary Swoveland的代码。
class Array
  def sq_convert(*args)
    zip(args).map { |string, meth| string.public_send(meth) }
  end
  def lf_convert(*args)
    map { |s| s.public_send args.shift }
  end
end    

require 'benchmark'

n = 1_000_000
array = %w{name 4 tag 0.343}
args = [:to_s, :to_i, :to_sym, :to_f]

Benchmark.bmbm(15) do |x|
  x.report("Arup's super-quick   :") { n.times { array.sq_convert(*args) } }
  x.report("Cary's lightning-fast:") { n.times { array.lf_convert(*args) } }
end

# Rehearsal ----------------------------------------------------------
# Arup's super-quick   :   2.910000   0.000000   2.910000 (  2.922525)
# Cary's lightning-fast:   2.150000   0.010000   2.160000 (  2.155886)
# ------------------------------------------------- total: 5.070000sec

#                             user     system      total        real
# Arup's super-quick   :   2.780000   0.000000   2.780000 (  2.784528)
# Cary's lightning-fast:   2.090000   0.010000   2.100000 (  2.099337)