Elegant implementation of "map (+1) list" in ruby

The short code in the header is in Haskell, it does something like

list.map {|x| x + 1} 

in ruby.

So far I know this manner, but I want to know if there are even more elegant manners for realizing the same in ruby, as in Haskell.

I really like the to_proc shortcut in ruby, like this form:

 [1,2,3,4].map(&:to_s) [1,2,3,4].inject(&:+) 

But this only trick exactly matches the argument number between Proc and the method.

I am trying to find a way to pass one or more arguments to Proc and without using a useless temporary block / variable, like what the first demo does.

I want to do like this:

 [1,2,3,4].map(&:+(1)) 

Do rubies have similar manners for this?

+6
source share
6 answers

Use ampex gem, which allows you to use X methods to create any one of a single variable. Here is an example from its specification:

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

If you just want to add it, you can use the succ method:

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

If you want to add two, you can use lambda:

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

For arbitrary values, you can use the lambda that builds lambdas:

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

You can also use the lambda generation method:

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

You cannot do this directly by default map . However, it is quite simple 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 is as follows:

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

In this particular case, you can use the following:

 [1, 2, 3, 4].map(&1.method(:+)) 

However, this only works because + not associative. For example, this does not work for - .

+2
source

Ruby does not support native support for this function, but you can create your own extension or use the small ampex 'stone. It defines a global variable X with the extended functionality "to_proc".

This gives you the opportunity to do this:

 [1,2,3].map(&X.+(1)) 

Or even this:

 "alpha\nbeta\ngamma\n".lines.map(&X.strip.upcase) 
+1
source

If you just want to add 1, you can use next or succ :

 [1,2,3,4].map(&:next) [1,2,3,4].map(&:succ) 
0
source

Source: https://habr.com/ru/post/916697/


All Articles