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

Ruby多层Hash遍历赋值时同键数据被覆盖问题如何解决

问题原因

Hash被覆盖的核心问题出在这行代码:

calendario_hash['calendario_status'][ano][mes][dia][hora]['audiencias'] = []

你每次遍历audiencia记录时,无论对应小时下的audiencias数组是否已经存在,都会强制重置为空数组,之前追加的记录自然就被覆盖了,只会保留最后一条遍历的记录。

修改方案

只需要把这行数组初始化的逻辑改成「数组不存在时才初始化」即可,同时还可以优化冗余的数据库查询逻辑(你开头已经取过pendente状态,不需要再重复查库),完整修改后代码如下:

audiencias = Documento::Audiencia.obter_audiencias_por_periodo(orgao_id, data_inicial, data_final)
audiencias.each do |audiencia|
  ano = audiencia.dth_audiencia.year
  mes = audiencia.dth_audiencia.month - 1
  dia = audiencia.dth_audiencia.day
  hora = audiencia.dth_audiencia.hour
  situacao = audiencia.pendente?

  # 逐层初始化Hash,避免undefined method `[]=' for nil:NilClass错误
  calendario_hash['calendario_status'] ||= {}
  calendario_hash['calendario_status'][ano] ||= {}
  calendario_hash['calendario_status'][ano][mes] ||= {}
  calendario_hash['calendario_status'][ano][mes][dia] ||= {"pendente" => situacao}
  calendario_hash['calendario_status'][ano][mes][dia][hora] ||= {}
  # 只有audiencias数组不存在时才初始化,不要每次都重置
  calendario_hash['calendario_status'][ano][mes][dia][hora]['audiencias'] ||= []

  audiencia_serializado = JSON.parse(audiencia.to_json(
    :only => [:id, :desc_audiencia, :dth_audiencia, :finalizada, :nr_processo_judicial],
    :include => {
      :objeto_tramitacao => {:only => [:id, :nr_objeto_tramitacao, :referencia]},
      :audiencia_tipo => {:only => [:id, :nm_audiencia_tipo]}
    }
  ))
  # 直接用之前已经拿到的situacao,不需要重复查库
  audiencia_serializado['audiencia']['pendente'] = situacao
  calendario_hash['calendario_status'][ano][mes][dia][hora]['audiencias'] << audiencia_serializado['audiencia']
end

可选优化(简化Hash初始化逻辑)

如果希望省略逐层判断nil的冗余代码,可以给calendario_hash设置默认Proc,自动生成嵌套Hash:

# 提前设置Hash的默认结构,不需要每次遍历都判断nil
calendario_hash['calendario_status'] ||= Hash.new { |h, k| h[k] = Hash.new { |h2, k2| h2[k2] = Hash.new { |h3, k3| h3[k3] = Hash.new { |h4, k4| h4[k4] = {} } } } }

audiencias.each do |audiencia|
  ano = audiencia.dth_audiencia.year
  mes = audiencia.dth_audiencia.month - 1
  dia = audiencia.dth_audiencia.day
  hora = audiencia.dth_audiencia.hour
  situacao = audiencia.pendente?

  calendario_hash['calendario_status'][ano][mes][dia]["pendente"] ||= situacao
  calendario_hash['calendario_status'][ano][mes][dia][hora]['audiencias'] ||= []

  # 后续序列化、追加记录的逻辑不变
end

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 21:39:03