如何过滤哈希数组以仅获取另一个数组中的键?

ped*_*ete 31 ruby arrays hash

我正在尝试为数组中的每个哈希获取一个键的子集.

哈希实际上要大得多,但我认为这更容易理解:

[
  {
    id:2,
    start: "3:30",
    break: 30,
    num_attendees: 14
  },
  {
    id: 3,
    start: "3: 40",
    break: 40,
    num_attendees: 4
  },
  {
    id: 4,
    start: "4: 40",
    break: 10,
    num_attendees: 40
  }
]
Run Code Online (Sandbox Code Playgroud)

我想只得到idstart价值观.

我试过了:

return_keys = ['id','start']
return_array = events.select{|key,val|  key.to_s.in? return_keys}
Run Code Online (Sandbox Code Playgroud)

但是这会返回一个空数组.

And*_*all 45

这应该做你想要的:

events.map do |hash|
  hash.select do |key, value|
    [:id, :start].include? key
  end
end
Run Code Online (Sandbox Code Playgroud)

可能更快(但不那么漂亮)的解决方案:

events.map do |hash|
  { id: hash[:id], start: hash[:start] }
end
Run Code Online (Sandbox Code Playgroud)

如果你需要return_keys动态:

return_keys = [:id, :start]
events.map do |hash|
  {}.tap do |new_hash|
    return_keys.each do |key|
      new_hash[key] = hash[key]
    end
  end
end
Run Code Online (Sandbox Code Playgroud)

请注意,在您的代码中,select数组中选择元素,因为这是您调用它的内容,但不会更改数组中包含的哈希值.

如果您关注性能,我会对此处列出的所有解决方案(代码)进行基准测试:

                user     system      total        real
amarshall 1  0.140000   0.000000   0.140000 (  0.140316)
amarshall 2  0.060000   0.000000   0.060000 (  0.066409)
amarshall 3  0.100000   0.000000   0.100000 (  0.101469)
tadman 1     0.140000   0.010000   0.150000 (  0.145489)
tadman 2     0.110000   0.000000   0.110000 (  0.111838)
mu           0.130000   0.000000   0.130000 (  0.128688)
Run Code Online (Sandbox Code Playgroud)


mu *_*ort 32

如果你碰巧使用Rails(或者不介意拉入全部或部分ActiveSupport),那么你可以使用Hash#slice:

return_array = events.map { |h| h.slice(:id, :start) }
Run Code Online (Sandbox Code Playgroud)

Hash#slice 做了一些额外的工作,但它可能足够快,你不会注意到它的小哈希和清晰度是相当不错的.

  • 实际上,如果你不在Rails中,你需要'require'active_support/core_ext'.需要明确加载核心扩展,因此只需要`require'active_support`'就行不通.(我这样说是因为后者是大多数人会考虑的"拉入所有的ActiveSupport".) (5认同)