簡體   English   中英

如何通過給定的鍵數組減少 Ruby 哈希?

[英]How to reduce a Ruby hash by a given array of keys?

我正在尋找一種簡單的方法來復制/減少散列,但只包含在鍵數組中指定的鍵/值。

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 })

如果散列有非常多的鍵和/或想要的鍵的數組非常大(可能不太可能),

original_hash.select { |k, v| wanted_keys.include?(k) }

由於線性搜索將是相對低效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}

wanted_keysoriginal_hash中這些鍵的值匹配,然后將結果數組轉換為哈希

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

在Ruby v2.0之前, Array#to_h剛出道的時候,會這樣寫

Hash[wanted_keys.zip(original_hash.values_at(*wanted_keys))]

這是為了你的規范通過:)

original_hash.slice(*wanted_keys)

如果你碰巧使用 Rails,你可以使用Hash#slice

require "active_support/core_ext/hash"

original_hash = { one: 1, two: 'too', three: 3 }
wanted_keys = [:one, :three]
new_hash = original_hash.slice *wanted_keys
#=> {:one=>1, :three=>3}

Hash#slice方法的實現存在於 Active 支持核心擴展代碼rails/activesupport/lib/active_support/core_ext/hash/slice.rb

如果你不想迭代整個Hash ,你可以使用each_with_object

original_hash = {one: 1, two: 'too', three: 3}

wanted_keys = [:one, :three]

# iterate only array of keys
new_hash = wanted_keys.each_with_object({}) do |key, exp|
  exp[key] = original_hash[key] if original_hash[key]
end

您可以嘗試類似(下面的低效解決方案)

original_hash.select{|k,v| wanted_keys.include? k }

我並不完全依賴我的 Ruby-foo,所以我不確定這是否返回列表或哈希。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM