Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to call different methods as given in an array

Especially when working with structs, it would be nice to be able to call a different method per each element in an array, something like this:

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

Are there any simple one-liners, ActiveSupport methods, etc. to do this easily?

like image 610
hololeap Avatar asked Dec 04 '25 15:12

hololeap


1 Answers

I would do this:

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]

I included the last line to show that convert leaves args unchanged, even though args is emptied within convert. That's because args was splatted before being passed to convert.

As per @Arup's request, I've benchmarked his and my solutions:

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)
like image 121
Cary Swoveland Avatar answered Dec 07 '25 05:12

Cary Swoveland



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!