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

Ruby哈希数组过滤遇nil报错:如何处理properties为nil的元素?

问题描述

现有如下Ruby哈希数组:

question["options"]
=> [{"id"=>10217, "title"=>{"English"=>"Da A a E"}, "value"=>"Da A a E", "properties"=>{"disabled"=>false}},
 {"id"=>10218, "title"=>{"English"=>"Profondo"}, "value"=>"Profondo", "properties"=>{"disabled"=>true, "piping_exclude"=>"false", "show_rules"=>nil, "show_rules_logic_map"=>nil}},
 {"id"=>10219, "title"=>{"English"=>"La macchina da caffè a capsule"}, "value"=>"La macchina da caffè a capsule", "properties"=>{"disabled"=>true, "piping_exclude"=>"false", "show_rules"=>nil, "show_rules_logic_map"=>nil}},
 {"id"=>10234, "title"=>{"English"=>"Extender Wifi"}, "value"=>"Extender Wifi", "properties"=>{"disabled"=>true, "piping_exclude"=>"false", "show_rules"=>nil, "show_rules_logic_map"=>nil}},
 {"id"=>10246, "title"=>{"English"=>"Da A a F"}, "value"=>"Da A a F", "properties"=>{"disabled"=>false}},
 {"id"=>10247, "title"=>{"English"=>"Sistematico"}, "value"=>"Sistematico", "properties"=>{"disabled"=>true, "piping_exclude"=>"false", "show_rules"=>nil, "show_rules_logic_map"=>nil}},
 {"id"=>10250, "title"=>{"English"=>"4"}, "value"=>"4", "properties"=>{"disabled"=>true, "piping_exclude"=>"false", "show_rules"=>nil, "show_rules_logic_map"=>nil}},
 {"id"=>10252, "title"=>{"English"=>"Ruote"}, "value"=>"Ruote", "properties"=>{"disabled"=>true, "piping_exclude"=>"false", "show_rules"=>nil, "show_rules_logic_map"=>nil}},
 {"id"=>10268, "title"=>{"English"=>"Sub 8 GHz"}, "value"=>"Sub 8 GHz", "properties"=>{"disabled"=>true, "piping_exclude"=>"false", "show_rules"=>nil, "show_rules_logic_map"=>nil}},
 {"id"=>10273, "title"=>{"English"=>"La copertura sul territorio"}, "value"=>"La copertura sul territorio", "properties"=>{"disabled"=>true, "piping_exclude"=>"false", "show_rules"=>nil, "show_rules_logic_map"=>nil}},
 {"id"=>10280, "title"=>{"English"=>"Da A a G"}, "value"=>"Da A a G", "properties"=>nil}]

需要过滤数组,移除所有["properties"]["disabled"]为true的元素,同时将保留的元素转换为指定结构。原代码如下:

question["options"].filter{ |o|
  unless o["properties"].dig("disabled")
    {
     "value": o["value"],
     "id": o["id"],
     "text": {
      "it": o["title"]["English"]
     }
    }
  end
}

但因最后一个元素的properties为nil,执行时抛出错误:

undefined method `dig' for nil:NilClass
解决办法

问题出在当properties为nil时,直接调用dig会触发NoMethodError。可以通过两种方式修复:

方法一:使用安全导航操作符&.

结合filter_map(同时完成过滤和映射,比filter更适合当前场景),代码如下:

question["options"].filter_map do |o|
  # 仅当disabled不为true时保留元素:properties为nil 或 disabled为false
  next unless o["properties"]&.dig("disabled") != true

  {
    "value": o["value"],
    "id": o["id"],
    "text": {
      "it": o["title"]["English"]
    }
  }
end
  • &.是Ruby的安全导航操作符,当o["properties"]为nil时,o["properties"]&.dig("disabled")会返回nil,不会触发报错;
  • filter_map会自动忽略next返回的nil,只收集我们构造的哈希对象。

方法二:用fetch给properties设置默认空哈希

如果偏好更明确的默认值处理,可使用fetch方法:

question["options"].filter_map do |o|
  # 当properties不存在时,返回空哈希,避免dig报错
  disabled = o.fetch("properties", {}).dig("disabled")
  # 仅当disabled为true时跳过该元素
  next if disabled == true

  {
    "value": o["value"],
    "id": o["id"],
    "text": {
      "it": o["title"]["English"]
    }
  }
end
  • o.fetch("properties", {})确保即使properties为nil,也能拿到空哈希,调用dig不会报错;
  • 空哈希调用dig("disabled")返回nil,不会触发next if disabled == true,因此properties为nil的元素会被保留。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 19:05:32