Published in

Geek Culture

# Iterating Through a Hash Where the First Key is an Array…of Hashes

Earlier this week I went through a technical interview where I did not finish the coding challenge in the specified time frame, but took some time afterward to tackle it and eventually solve it. I’ve altered the question in this post so it is not the exact one that was presented, but requires the same steps in order to solve. The two interviewers were absolutely fantastic — they were encouraging and supportive, and clearly enjoyed the company they work for. I think there is no greater testament to a company’s culture than the genuine happiness and feedback from its employees.

The challenge I faced while tackling this problem during the call was forgetting how to select keys/values in a hash vs. an array. Having just worked on an API call that required me to iterate through hashes, I was frustrated with myself for blanking out. However, everything is a learning experience and only makes us stronger programmers. This was solved using Ruby.

Here’s the scenario:

You are deciding how much money you should budget for birthday presents for the next few months. You have a base budget and know which months have more birthdays than others. You increase your budget if a specific month has a lot of birthdays in it. Your list looks like the following:

`base_budget = 100birthdays = {  birthday_count: [  {month: "April", type: "add", factor: "50"},   {month: "May", type: "add", factor: "10.5"},   {month: "June", type: "none"},   {month: "July", type: "multiply", factor: "2"}  ]}`

Based on this information, write a method that will take in the base budget, the birthday list, and the month from that list. Depending on what month is provided, the base budget will change depending on the type and factor. As an example, for July we expect the base budget of 100 to be multiplied by 2.

Breaking down the problem:

From what we have so far, we can conclude that our method takes in three arguments.

`def adjust_birthday_budget(base_budget, birthdays, month)end`

We also know that birthdays has a key of :birthday_count, which has an array of hashes we’ll want to access. Let’s take this one step at a time. First, let’s make sure we can access the contents of :birthday_count. How can we go about having the program read through each item and give it back to us? If you guessed iteration, you are correct. Hop on over to Repl.it, copy and paste the base budget and birthday data, and try the following:

`birthdays[:birthday_count].each do |bc|   puts bcend`

Hit “run” and you should see the following output:

The next part of the method requires us to access the individual keys and values of each hash within the :birthday_count array. If we were able to pull out the initial information we wanted with birthdays[:birthday_count], how could we go about pulling the :month, :type and :factor keys? Try the following separately:

`birthdays[:birthday_count].each do |bc|   puts bc[:month]end# => April, May, June, Julybirthdays[:birthday_count].each do |bc|   puts bc[:type]end#=> add, add, none, multiplybirthdays[:birthday_count].each do |bc|   puts bc[:factor]end#=> 50, 10, , 2`

Woo! We are successfully pulling the values of our keys. So now the question is, what the heck do we do with all of this?!

Let’s revisit the problem at hand. We want the base budget which has the value of 100, to be affected or not based on the value of type and factor of the respective month submitted to the method.

In other words, if the month is set to April, we want the budget to increase by 50, because the type is set to addition. Sounds like we need an if/else statement!

`if bc[:month] == month   if bc[:type] == "multiply"    new_base_budget = base_budget * bc[:factor].to_f  elsif bc[:type] == "add"    new_base_budget = base_budget + bc[:factor].to_f  else    new_base_budget = base_budget  endputs new_base_budgetend`

What we’re saying here, is that if the key :month is equal to the argument we’re passing in (base_budget, birthdays, “July”), and if the value of the :type key of that month is set to “multiply”, do the following math to the base budget. Since we know how to access the value of :factor, we can multiply the base_budget by using that code “bc[:factor]”. Oh wait! The value of :factor is set to a string. We can use .to_i method to change it to an integer. However, what if one of these values was a decimal? Instead of .to_i, we can use .to_f. The “f” stands for float, which represents none whole numbers (i.e. decimals).

Next we write the condition of what we want the program to do if the value of the :type key is set to addition. Otherwise, nothing will happen to the base budget. The new logic of base_budget is stored in a variable, “new_base_budget”. After this condition statement is ended, we return the new_base_budget value. Let’s put it all together.

`base_budget = 100birthdays = {  birthday_count: [  {month: "April", type: "add", factor: "50"},   {month: "May", type: "add", factor: "10.5"},   {month: "June", type: "none"},   {month: "July", type: "multiply", factor: "2"}  ]}def adjust_birthday_budget(base_budget, birthdays, month) birthdays[:birthday_count].each do |bc|  if bc[:month] == month     if bc[:type] == "multiply"      new_base_budget = base_budget * bc[:factor].to_f    elsif bc[:type] == "add"      new_base_budget = base_budget + bc[:factor].to_f    else      new_base_budget = base_budget    end  puts new_base_budget  end endend=>#side note: you don't need the 'puts' but for Repl.it I did have to use it to see the output in the terminal. If there is no 'puts', a return is implicitly implied. `

There you have it, however, we’re not quite finished. The problem has been successfully solved, but can the solution be refactored? After reading up on Ruby’s ternary operator, I decided it could be. The following is how I refactored the above solution:

`def adjust_birthday_budget(base_budget, birthdays, month) birthdays[:birthday_count].each do |bc|   bc[:month] == month && bc[:type] == "multiply" ?   base_budget *= bc[:factor].to_f : base_budget   bc[:month] == month && bc[:type] == "add" ?   base_budget += bc[:factor].to_f : base_budget end   puts base_budgetendadjust_birthday_budget(base_budget, birthdays, "July")`

This took me some time and messing around with to figure out, so explaining the syntax will possibly be done in another post. However, if you plug this into Repl.it, you’ll see it works the same as the previous solution.

There you have it friends! I hope this was helpful, and am always open to feedback as I really want these posts to be supportive and educative to fellow programmers. To all aspiring software engineers/developers such as myself, do not get discouraged if you are unable to solve a problem during a coding interview. Keep practicing and never stop learning.

--

--

--

## More from Geek Culture

A new tech publication by Start it up (https://medium.com/swlh).

## Diana M.

Software Engineering graduate with a penchant for matcha lattes and baked goods. Most of my content will consist of RoR, JS, HTML/CSS, and React.