arr = [{a:1}, {a:2}],要得到 [1,2],一般这样写:
arr.map{|hash| hash[:a]}
我知道有一种写法是:
['a','b'].map(&:upcase)
如果能写成这样就好了: arr.map(&:[:a])
当然,这样是报错的。
有没有类似的写法呢?
ruby 内置的方法应该是没有,map 不支持额外的参数,所以也没有 arr.map(&:[], :a)。自己搞一个:
class Array def map_hash_value(key) map { |x| x[key] } end end [{a: 1}, {a: 2}].map_hash_value(:a) # => [1, 2]
没有更简洁的写法,不是代码越短就越好的,要简单易懂。 &就是个语法糖,如果语法不适用这个语法糖就别强求
因为 Array(Hash) 不是原生类型,所以没有。
要那么短做啥呢
extract = ->(k) { ->(h) { h[k] } } arr.map(&extract[:a])
via: https://stackoverflow.com/questions/20179636/ruby-using-the-methodname-shortcut-from-array-mapmethodname-for-hash-key
过分的求简短没意义
你可以给 Symbol 加个 patch
class Symbol def call(*args, &block) ->(caller, *rest) { caller.send(self, *rest, *args, &block) } end end
这样任意的 proc shorthand 写法就可以写成
arr.map(&:[].(:a))
但是这样的可读性反而比不上非 shorthand 写法,记得 ruby 有讨论一个新的语法支持 shorthand argument, 语法类似这样,&0, &1, &N 代表 proc 的第 N 个元素,不过还没有被接受:
arr.map(&0[:a])
因为某些地方这种相同的代码重复很多次,所以想重构。
2.7 后的写法:arr.map{ _1[:a] },比你想要的 arr.map(&:[:a]) 还要简洁一些
重写