Ruby ruby map 有没有更简洁的写法

tomanderson · 2021年02月04日 · 最后由 easonlovewan 回复于 2021年02月19日 · 650 次阅读

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) 不是原生类型,所以没有。

要那么短做啥呢

过分的求简短没意义

你可以给 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])
xiaox 回复

因为某些地方这种相同的代码重复很多次,所以想重构。

2.7 后的写法: arr.map{ _1[:a] }, 比你想要的 arr.map(&:[:a]) 还要简洁一些

需要 登录 后方可回复, 如果你还没有账号请 注册新账号