我已经习惯了能够缩短
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,假设有某种解决方案。
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]
最短方式可能会使用“编号块参数”。
some_array_of_arrays.map { _1[4] }
在 Ruby 3.4 中,您应该能够使用 it
而不是
_1
(https://bugs.ruby-lang.org/issues/18980)