0

我正在通过对JSON 文档的模式匹配来试验Ruby 2.7 中的新模式匹配功能。我想用它来匹配具有某些特征的数组元素。在我的例子中,有一个区域数据数组存储为哈希值,每个哈希值都有一个 id。我只需要使用如下所示的与哈希匹配:id10

require 'net/http'
require 'json'

HOSPITAL_DATA_URI = URI("https://www.dph.illinois.gov/sitefiles/COVIDHospitalRegions.json?nocache=1").freeze

hospital_data = JSON.parse(Net::HTTP.get(HOSPITAL_DATA_URI), symbolize_names: true)
region_values = hospital_data[:regionValues]

case region_values
  in [{id: 10, **unimportant_attributes}, **non_region_10_hashes]
    puts 'We found region 10!'
else
  puts 'aw shucks'
end

puts "...but Region 10 does exist" if region_values.find {|region| region[:id] == 10}

#=> aw shucks
#=> ...but Region 10 does exist

我希望它打印“我们找到了 10 区!” 但事实并非如此。

是否可以使用 Ruby 模式匹配来做到这一点?

4

2 回答 2

1

u/zvero_kha在这里有答案。基本上我正在寻找的东西被称为“查找模式”,并且最近才被合并到 Ruby 中。预计将出现在 Ruby 3.0 版本中。在我的情况下你将如何使用它是:

case region_values
  # Note the "splat-like" asterisks. These are the "find patterns."
  in [*, {id: 10} => r10, {id: 11} => r11, *]
    puts "Region 10: #{r10}"
    puts "Region 11: #{r11}"
    # Note that both r10 and r11 are available in this block of code here
else
  puts 'aw shucks'
end

Matz对使用这些“查找模式”的解释非常有用。

于 2020-09-22T01:55:24.207 回答
0

我们发现给定的代码为 检索以下值region_values

region_values
  #=> [
    {:region=>"Region01", :id=>1, :region_description=>"1 - Rockford Region Hospitals",
     :ICUAvail=>126, :ICUCapacity=>234, :VentsAvailable=>296, :VentsCapacity=>359},
    {:region=>"Region02", :id=>2, :region_description=>"2 - Peoria Region Hospitals",
     :ICUAvail=>140, :ICUCapacity=>304, :VentsAvailable=>398, :VentsCapacity=>496},
    {:region=>"Region03", :id=>3, :region_description=>"3 - Springfield Region Hospitals",
     :ICUAvail=>77, :ICUCapacity=>150, :VentsAvailable=>350, :VentsCapacity=>410},
    {:region=>"Region04", :id=>4, :region_description=>"4 - Edwardsville Region Hospitals",
     :ICUAvail=>61, :ICUCapacity=>113, :VentsAvailable=>134, :VentsCapacity=>158},
    {:region=>"Region05", :id=>5, :region_description=>"5 - Marion Region Hospitals",
     :ICUAvail=>64, :ICUCapacity=>107, :VentsAvailable=>294, :VentsCapacity=>309},
    {:region=>"Region06", :id=>6, :region_description=>"6 - Champaign Region Hospitals",
     :ICUAvail=>70, :ICUCapacity=>162, :VentsAvailable=>260, :VentsCapacity=>287},
    {:region=>"Region07", :id=>7, :region_description=>"7 - Southwest Suburbs Region Hospitals",
     :ICUAvail=>175, :ICUCapacity=>484, :VentsAvailable=>444, :VentsCapacity=>589},
    {:region=>"Region08", :id=>8, :region_description=>"8 - West Suburbs Region Hospitals",
     :ICUAvail=>176, :ICUCapacity=>480, :VentsAvailable=>319, :VentsCapacity=>550},
    {:region=>"Region09", :id=>9, :region_description=>"9 - Northwest Suburbs Region Hospitals",
     :ICUAvail=>238, :ICUCapacity=>452, :VentsAvailable=>438, :VentsCapacity=>533},
    {:region=>"Region10", :id=>10, :region_description=>"10 - Northeast Suburbs Region Hospitals",
     :ICUAvail=>112, :ICUCapacity=>206, :VentsAvailable=>190, :VentsCapacity=>234},
    {:region=>"Region11", :id=>11, :region_description=>"11 - City of Chicago Region Hospitals",
     :ICUAvail=>395, :ICUCapacity=>1064, :VentsAvailable=>1392, :VentsCapacity=>1803}
]

在发布此之前,我不知道 Ruby v2.7 中的新模式匹配功能。读完这篇文章后,我真的不明白这如何适用于您的问题(尽管该功能本身很有趣并且似乎很有用)。你可以写:

region_values.each do |h|
  puts case h
  in {id: 10}
    'We found region 10!'
  else
    'aw shucks'
  end
end
aw shucks
aw shucks
aw shucks
aw shucks
aw shucks
aw shucks
aw shucks
aw shucks
aw shucks
We found region 10!
aw shucks

或者

found = region_values.find do |h|
  case h
  in {id: 10}
    true
  end
end
puts found ? 'We found region 10!' : 'aw shucks'
We found region 10!

但新功能的应用也不是很有趣。

于 2020-09-21T21:42:02.380 回答