You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Ruby多层哈希补全:为分组统计结果填充缺失键的0值

补全多层哈希中缺失的键并设置默认值为0

开发Rails API做车辆查询与分组统计时,PostgreSQL的GROUP BY不会返回计数为0的分组结果,导致响应哈希中缺失对应键。现有实现仅支持两层哈希的缺失键填充,无法处理三层及更复杂的多层结构,需要实现能补全所有层级缺失键、并将值设为0的方法。

示例输入(三层哈希)

{
  AUDI: {
    Deregistered: {
      Diesel: 56
    },
    Registered: {
      Petrol: 379,
      Diesel: 270,
      Electric: 447
    }
  },
  TESLA: {
    Registered: {
      Electric: 779
    }
  }
}

期望输出

{
  AUDI: {
    Deregistered: {
      Petrol: 0,
      Diesel: 56,
      Electric: 0
    },
    Registered: {
      Petrol: 379,
      Diesel: 270,
      Electric: 447
    }
  },
  TESLA: {
    Deregistered: {
      Petrol: 0,
      Diesel: 0,
      Electric: 0
    },
    Registered: {
      Petrol: 0,
      Diesel: 0,
      Electric: 779
    }
  }
}

现有方法的问题

原代码的collect_keys会把所有层级的键混为一谈,fill_missing_keys用同一套键去填充所有层级,这不符合需求——不同层级的键集合是独立的(比如第一层是品牌,第二层是车辆状态,第三层是燃料类型),必须按层级分别处理。

解决方案

先构建每个层级的完整键集合,再递归遍历哈希,为每个层级补全缺失的键,同时为缺失的父键创建完整的子层级结构并填充默认值。

完整实现代码

# 构建每个层级的完整键集合,返回层级化的键哈希
def build_key_hierarchy(hash, hierarchy = {})
  return hierarchy if hash.empty?

  current_level_keys = hash.keys.uniq
  hierarchy[:current] = current_level_keys

  # 收集所有子哈希,递归处理下一层级
  child_hashes = hash.values.select { |v| v.is_a?(Hash) }
  unless child_hashes.empty?
    combined_child_hash = child_hashes.reduce({}, :merge)
    hierarchy[:children] = build_key_hierarchy(combined_child_hash)
  end

  hierarchy
end

# 递归填充缺失的键与层级结构
def fill_missing_hierarchy(hash, key_hierarchy, default_value = 0)
  # 补全当前层级的缺失键
  key_hierarchy[:current].each do |key|
    unless hash.key?(key)
      # 如果有子层级,创建对应的空哈希并递归填充
      hash[key] = if key_hierarchy[:children]
                    fill_missing_hierarchy({}, key_hierarchy[:children], default_value)
                  else
                    default_value
                  end
    else
      # 如果当前值是哈希且有子层级,递归处理子哈希
      if hash[key].is_a?(Hash) && key_hierarchy[:children]
        fill_missing_hierarchy(hash[key], key_hierarchy[:children], default_value)
      end
    end
  end

  hash
end

# 对外暴露的入口方法
def complete_hash(hash, default_value = 0)
  key_hierarchy = build_key_hierarchy(hash)
  fill_missing_hierarchy(hash, key_hierarchy, default_value)
end

代码说明

  1. build_key_hierarchy:递归遍历输入哈希,收集每个层级的所有唯一键,生成层级化结构。比如示例输入会生成:
    {
      current: [:AUDI, :TESLA],
      children: {
        current: [:Deregistered, :Registered],
        children: {
          current: [:Diesel, :Petrol, :Electric]
        }
      }
    }
    
  2. fill_missing_hierarchy:根据层级键结构递归补全缺失键——若键不存在,有子层级则创建空哈希并递归填充子结构,无则直接设默认值;若键已存在且值为哈希,继续递归处理子哈希。
  3. complete_hash:入口方法,调用前两个方法完成整个哈希的补全。

测试示例

input = {
  AUDI: {
    Deregistered: {
      Diesel: 56
    },
    Registered: {
      Petrol: 379,
      Diesel: 270,
      Electric: 447
    }
  },
  TESLA: {
    Registered: {
      Electric: 779
    }
  }
}

puts complete_hash(input).inspect

运行后会得到期望的输出结果。

内容的提问来源于stack exchange,提问作者TobiasKnudsen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 01:27:08