如何通过给定的键数组减少 Ruby 哈希?

And*_*rew 2 ruby

我正在寻找一种简单的方法来复制/减少散列,但只包含在键数组中指定的键/值。

original_hash = { one: 1, two: 'too', three: 3 }
wanted_keys = [:one, :three]
new_hash = # do something with the hash
expect(new_hash).to eq({ one: 1, three: 3 })
Run Code Online (Sandbox Code Playgroud)

Car*_*and 6

如果散列具有非常多的键和/或所需键的数组非常大(可能不太可能),

original_hash.select { |k, v| wanted_keys.include?(k) }
Run Code Online (Sandbox Code Playgroud)

效率相对较低,因为 的wanted_keys每个original_hash键都需要线性搜索。这里有两种方法可以加快速度。(@Lucas 的解决方案是第三种方式。)

转换wanted_keys为集合

require 'set'

wanted_keys_set = wanted_keys.to_set
original_hash.select { |k, v| wanted_keys_set.include?(k) }
  #=> {:one=>1, :three=>3}
Run Code Online (Sandbox Code Playgroud)

wanted_keys与这些键的值匹配,original_hash然后将结果数组转换为哈希

wanted_keys.zip(original_hash.values_at(*wanted_keys)).to_h
  #=> {:one=>1, :three=>3}
Run Code Online (Sandbox Code Playgroud)

在Ruby v2.0之前,Array#to_h首次亮相时,会这样写

Hash[wanted_keys.zip(original_hash.values_at(*wanted_keys))]
Run Code Online (Sandbox Code Playgroud)


小智 6

这是为了你的规范通过:)

original_hash.slice(*wanted_keys)


bk5*_*545 -1

您可以尝试类似的方法(下面的低效解决方案)

original_hash.select{|k,v| wanted_keys.include? k }
Run Code Online (Sandbox Code Playgroud)

我不太了解 Ruby-foo,所以我不确定这是否返回列表或哈希。

  • 当作者指出答案可能正确也可能不正确时,答案有什么用呢?在发布答案之前先进行研究!`{}.method(:select).owner #=> Hash` 告诉您该方法是 `Hash#select`。假设您的代码有效,因为“select”返回一个哈希值,并给出文档的链接:[Hash#select](http://ruby-doc.org/core-2.2.0/Hash.html#method-i-选择)。我建议你编辑。 (5认同)