Array map, concise notation

I often encounter the following pattern:

enum.map {|e| e.f} # /1/
enum.map {|e| f(e)} # /2/

For the first case, I can get rid of writing the parameter e explicitly,
by using

enum.map(&:f) # /1/

Is it possible to write the second way too in a form, where I don’t need
to introduce a name for the parameter ‘e’?

Ronald

module Enumerable
def smap(s)
map { |a| eval “#{s}(a)” }
end
end

def sqr(a) a*a end
p [1,2,3].smap(:sqr)

p [1,2,3].smap(“Math.log”)

Regis d’Aubarede wrote in post #1181686:

map { |a| eval "#{s}(a)" }

Aaarrgghhh!!!

Technically speaking, this indeed solved my question, but …

I think I should have make clear, that I was looking for a solution NOT
involving eval :wink:

Thanks anyway!

Ronald

Or with variable arguments to the function, although this is probably
overkill:

module Enumerable
def smap(f,scope=nil,pos=0,*args)
if scope
m = scope.method(f)
else
m = Object.method(f)
end
a1 = args[0,pos]
a2 = args[pos…-1] || []
map{|a|m[*a1,a,*a2]}
end
end

def sqr(x)
x*x
end

def third(a,b,c,d,e)
c
end

p [1,2,3].smap(:sqr)

=> [1,4,9]

p [2,4].smap(:*,“xy”)

=> [“xyxy”,"xyxyxyxy]

p [1,2,3].smap(:log,Math)
p [10,100,1000].smap(:log,Math,0,10)
p [2,5].smap(:third,nil,2,0,0,0,0)
p [2,5].smap(:third,nil,1,0,0,0,0)

I agree that eval is to be avoided. How about:

module Enumerable
def smap(f,scope=nil)
if scope
m = scope.method(f)
else
m = Object.method(f)
end
map{|a|m[a]}
end
end

def sqr(x)
x*x
end

p [1,2,3].smap(:sqr)

=> [1,4,9]

p [2,4].smap(:*,“xy”)

=> [“xyxy”,"xyxyxyxy]

p [1,2,3].smap(:log,Math)

Dansei Yuuki wrote in post #1181688:

module Enumerable
def smap(f,scope=nil)
if scope
m = scope.method(f)
else
m = Object.method(f)
end
map{|a|m[a]}
end
end

Ingenious! This looks so useful, that it should go into the Ruby
core!

Ronald

This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.

| Privacy Policy | Terms of Service | Remote Ruby Jobs