Grouped Hash


Introduction

I’ve been doing lots of work in JS lately and I recently got to go back to rails and do some development in that. It was nice, it was like going back home for the holidays.

One of the things I had to do was group these codes and medical conditions together. They all had a condition, which is like the category. Some of them had a sub condition and they all had a Snomed code. Snomed codes are the identifier for the illness.

Organizing a class of conditions.

I decided to break the list into a class and have another class which acts likes my manager or parser. Responsible for formatting the data and doing weird things with it. I called that one Snomed and the other one SnomedCode.

class SnomedCode
  def initialize
  end

  def self.codes
  [
    { :condition => "Cancer",                :sub_condition => "Bone Cancer",         :snomed => "94222008"},
    { :condition => "Clotting Disorder",     :sub_condition => "Clotting Disorder",   :snomed => "64779008"},
    { :condition => "Heart Disease",         :sub_condition => "Angina",              :snomed => "194828000"},
    { :condition => "Lung Disease",          :sub_condition => "Asthma",              :snomed => "195967001"},
    { :condition => "No known condition",    :sub_condition => nil,                   :snomed => "160245001"},
  ]
  end
end


class Snomed
  attr_accessor :snomed_codes

  def initialize
    @snomed_codes = SnomedCode.codes
  end

  def all
    @snomed_codes
  end
end

So the challenge began

The challenge was to take the array of hashes inside the SnomedCode.codes and format it work with grouped_options_for_select in a select tag.

<div class="control-group">
  <%= f.label :illness, :class => 'control-label' %>
  <div class="controls">
    <%= f.select :illness, grouped_options_for_select(Snomed.new.grouped, @family_medical_history.illness, "Please Select a Illness") %>
  </div>
</div>

The example grouped_options_for_select has looks like this:

'North America' => [['United States','US'], 'Canada'],
'Europe' => ['Denmark','Germany','France']

Thats when I freaked the fuck out. How am I going to make my array of hashes look like that!

Ruby has a awesome hash api and one of the things you do is use a group by and loop through the list of values. It’s then just looping through those values and creating an array based on the sub conditions and snomed code. When the sub condition is empty, the condition takes it place.

  def grouped
		grouped = Hash.new
		all.group_by { |c| c[:condition] }.each { |c,v|
			group_val = Array.new
			v.each { |val|
				val_array = Array.new
				sub_condition = (val[:sub_condition].blank? ? c : val[:sub_condition])
				group_val.push(val_array.push(sub_condition, val[:snomed]))
			}
			grouped["#{c}"] =  group_val
		}
		return grouped
	end

The output is a hash that has it’s condition as the key, and it’s value as an array(s) of the sub condition and it’s snomed code.

 $ rails c
Loading development environment (Rails 3.2.17)
2.0.0-p247 :001 > Snomed.new.grouped
 => {"Cancer"=>[["Bone Cancer", "94222008"]], "Clotting Disorder"=>[["Clotting Disorder", "64779008"]], "Heart Disease"=>[["Angina", "194828000"]], "Lung Disease"=>[["Asthma", "195967001"]], "No known condition"=>[["No known condition", "160245001"]]}

As you can see below the options dropdown is now populated with the grouping of the condition. The entry with no sub condition is duplicated as the sub condition. When the form saves, the value that comes across as the illness is the snomedcode.

The End