Ruby中能否用map(&:method)简写提取数组哈希指定键值?
哈希数组的简洁提取写法
Ruby原生并不支持&:'first'这种直接提取哈希键值的简写,得先从你熟悉的&:to_f原理说起:
a.map(&:to_f)本质是a.map(&:to_f.to_proc)——符号:to_f会调用Symbol#to_proc方法生成一个Proc,作用是对每个元素调用该方法(也就是x.to_f)。但哈希的键查找是调用Hash#[]方法(比如x['first']),这是带参数的方法调用,没法直接用单个符号转Proc实现,而且字符串本身也没有to_proc方法,直接写&:'first'会抛出NoMethodError。
不过我们可以用几种方式实现类似的简洁效果:
1. 自定义提取Proc
直接写一个返回Proc的方法,把键作为参数传入:
def get(key) ->(hash) { hash[key] } end a = [{'first' => 1, 'second' => 4}, {'first' => 5, 'second' => 6}] a.map(&get('first')) # => [1, 5]
2. 用Proc的curry特性
利用Ruby Proc的curry化,把带多参数的Proc转换成可以分步传参的形式:
fetch = ->(key, hash) { hash[key] }.curry a.map(&fetch['first']) # => [1, 5]
这种方式不用额外定义方法,一行就能搞定,嵌套哈希场景也适用:
nested_data = [{user: {name: 'Alice'}}, {user: {name: 'Bob'}}] nested_fetch = ->(k1, k2, hash) { hash[k1][k2] }.curry nested_data.map(&nested_fetch[:user][:name]) # => ["Alice", "Bob"]
3. 扩展Array类实现pluck方法
如果经常需要做这种操作,可以给Array加一个类似Rails中pluck的方法:
class Array def pluck(key) map { |item| item[key] } end end a.pluck('first') # => [1, 5] nested_data.pluck(:user).pluck(:name) # => ["Alice", "Bob"]
这些方法都能帮你在处理大量嵌套哈希数组时,写出更简洁的代码,替代冗长的块写法。
内容的提问来源于stack exchange,提问作者hammer96
相关产品推荐
相关产品推荐

