如何扁平化含嵌套哈希与数组的哈希,确保值唯一?
扁平化嵌套哈希并保证值唯一的解决方案
我之前也踩过类似的坑,一开始把递归逻辑想复杂了绕进去,其实核心就是递归遍历+值去重两步,下面给你一个简洁的实现思路和代码:
核心思路
- 递归拆解所有嵌套结构:不管是哈希套哈希,还是数组里混哈希,都递归把所有键值对拉到顶层;
- 全程校验值唯一性:每添加一个键值对前,先检查结果哈希里是否已有这个值,避免重复;
- 数组单独处理:先对数组去重,再展开其中的嵌套哈希,非哈希元素去重后保留为原键的值。
代码实现(Ruby为例)
def flatten_and_deduplicate(hash) result = {} hash.each do |key, value| case value when Hash # 递归展开嵌套哈希,合并到结果中 nested_flattened = flatten_and_deduplicate(value) nested_flattened.each do |nested_key, nested_val| result[nested_key] = nested_val unless result.values.include?(nested_val) end when Array # 先对数组去重 deduplicated_array = value.uniq # 处理数组里的嵌套哈希 deduplicated_array.each do |item| if item.is_a?(Hash) nested_flattened = flatten_and_deduplicate(item) nested_flattened.each do |nested_key, nested_val| result[nested_key] = nested_val unless result.values.include?(nested_val) end end end # 保留数组中的非哈希值(去重后) non_hash_values = deduplicated_array.reject { |item| item.is_a?(Hash) } result[key] = non_hash_values unless non_hash_values.empty? || result.values.include?(non_hash_values) else # 普通值,仅当值未存在时添加 result[key] = value unless result.values.include?(value) end end result end
测试示例
假设你的源哈希是这样的:
source_hash = { name: "Alice", contacts: { email: "alice@example.com", phones: ["123456", "789012", "123456"] }, hobbies: ["reading", "hiking", { outdoor: "camping" }, "reading"] }
调用方法后得到的目标哈希:
{ :name=>"Alice", :email=>"alice@example.com", :phones=>["123456", "789012"], :outdoor=>"camping", :hobbies=>["reading", "hiking"] }
自定义调整说明
如果你的需求有细微差异,只需要修改对应分支的逻辑:
- 要是想把数组里的每个非哈希元素都作为单独键值对,可以把数组处理部分改成遍历元素直接添加(注意键重复的问题);
- 要是优先保留先出现的值,保持现有逻辑即可;如果想保留后出现的,只需要去掉值存在的判断直接覆盖。
内容的提问来源于stack exchange,提问作者wilcro
相关产品推荐
相关产品推荐

