Как передать аргумент для сокращения строки array.map?
Учитывая следующий массив a
:
a = [1, 2, 3, 4, 5]
Как мне сделать:
a.map { |num| num + 1 }
с использованием коротких обозначений:
a.map(&:+ 1)
или
a.map(&:+ 2)
где 1 и 2 - аргументы?
Ответы
Ответ 1
Вы не можете сделать это так. Оператор &
предназначен для превращения символов в procs.
a = [1, 2, 3, 4, 5]
puts a.map(&:to_s) # prints array of strings
puts a.map(&:to_s2) # error, no such method `to_s2`.
&
является сокращением для to_proc
:
def to_proc
proc { |obj, *args| obj.send(self, *args) }
end
Создает и возвращает новый proc. Как вы видите, вы не можете передать какие-либо параметры этому методу. Вы можете вызвать только вызванный proc.
Ответ 2
В этом случае вы можете сделать
a.map(&1.method(:+))
Но только потому, что 1 + x обычно совпадает с x + 1.
Вот обсуждение этой практики в контексте производительности.
Ответ 3
Вы не можете сделать это с помощью map
. Но посмотрите Facets 'Enumerable#map_send:
require 'facets'
[1, 2, 3].map_send(:+, 1)
#=> [2, 3, 4]
Написание собственной реализации довольно просто:
module Enumerable
def map_send(*args)
map { |obj| obj.send(*args) }
end
end
Ответ 4
Если вам действительно нужно, вы можете использовать Ampex библиотеку, но я не знаю, поддерживается ли она.