Elegantly implementing 'map (+1) list' in ruby

If you just want to add one then you can use the succ method:

>> [1,2,3,4].map(&:succ)
=> [2, 3, 4, 5]

If you wanted to add two, you could use a lambda:

>> add_2 = ->(i) { i + 2 }
>> [1,2,3,4].map(&add_2)
=> [3, 4, 5, 6]

For arbitrary values, you could use a lambda that builds lambdas:

>> add_n = ->(n) { ->(i) { i + n } }
>> [1,2,3,4].map(&add_n[3])
=> [4, 5, 6, 7]

You could also use a lambda generating method:

>> def add_n(n) ->(i) { i + n } end
>> [1,2,3,4].map(&add_n(3))
=> [4, 5, 6, 7]

Use the ampex gem, which lets you use methods of X to build up any proc one one variable. Here’s an example from its spec:

["a", "b", "c"].map(&X * 2).should == ["aa", "bb", "cc"]

You can't do it directly with the default map. However it's quite easy to implement a version that supports this type of functionality. As an example Ruby Facets includes just such a method:

require 'facets/enumerable'

[1, 2, 3, 4].map_send(:+, 10)
=> [11, 12, 13, 14]

The implementation looks like this:

def map_send(meth, *args, &block)
  map { |e| e.send(meth, *args, &block) }
end

Tags:

Ruby