Можете ли вы использовать сокращение Ruby для вызова метода, такого как метод доступа к массиву? - PullRequest
0 голосов
/ 29 октября 2018

Я привык к сокращению

some_array.map { |e| e.to_s }

до

some_array.map(&:to_s)

Есть ли способ сократить

some_array_of_arrays.map { |e| e[4] }

похоже на

some_array_of_arrays.map(&:[4])

Очевидно, я пробовал последний пример, но он не работает. В идеале решение должно быть обобщено на другие «странно отформатированные» вызовы методов, такие как [].

Я не заинтересован в любом решении Rails / ActiveSupport. Только обычный Ruby, при условии, что есть какое-то решение.

Ответы [ 2 ]

0 голосов
/ 29 октября 2018

вы можете использовать Proc :

> a = [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12], [13, 14]]
> third_elem = Proc.new {|x| x[2]}
> a.map(&third_elem)
#> [3, 7, 11, nil] 

OR

> a.map &->(s) {s[2]}
#=> [3, 7, 11, nil] 
0 голосов
/ 29 октября 2018

Опять же, вы можете построить его. Это не так элегантно, но ...

class Call
  def self.[](name, *args)
    self.new(name, *args)
  end

  def initialize(name, *args)
    @proc = Proc.new do |obj|
      obj.send(name, *args)
    end
  end

  def to_proc
    @proc
  end
end

fourth = Call.new(:[], 3)
[[1,2,3,4,5],[6,7,8,9,10]].map(&fourth)           # => [4, 9]
# or equivalently
[[1,2,3,4,5],[6,7,8,9,10]].map(&Call.new(:[], 3)) # => [4, 9]
[[1,2,3,4,5],[6,7,8,9,10]].map(&Call[:[], 3])     # => [4, 9]

Если вы хотите специализировать его для индексов, вы можете даже упростить до этого:

class Index
  def self.[](*args)
    self.new(*args)
  end

  def initialize(*args)
    @proc = Proc.new do |obj|
      obj[*args]
    end
  end

  def to_proc
    @proc
  end
end

[[1,2,3,4,5],[6,7,8,9,10]].map(&Index[3])     # => [4, 9]

Или, намного короче, как продемонстрировал @muistooshort в комментариях, если вы не хотите иметь полный класс, посвященный этому:

index = ->(*ns) { ->(a) { a[*ns] } }
[[1,2,3,4,5],[6,7,8,9,10]].map(&index[3])     # => [4, 9]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...