Geek Culture
Published in

Geek Culture

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

How it can feel working with 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 = 100
birthdays = {
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 bc
end

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

We have successfully pulled the data from the birthday_count array

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, July
birthdays[:birthday_count].each do |bc|
puts bc[:type]
end
#=> add, add, none, multiply
birthdays[: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
end
puts new_base_budget
end

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 = 100
birthdays = {
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
end
end
=>#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.
Try it out in Repl.it! Play around with the different months and see the results in the terminal.

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_budget
end
adjust_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.

Thanks for reading ~

--

--

--

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

Recommended from Medium

DevOps For Dummies

Welcome to join #MetaVisa Discord and share 4500$MESA

de-concat mp4 files

WHAT ARE HEADLESS CONTENT MANAGEMENT SYSTEMS?

Introducing: The Smerf Blog!

Integrating Folium maps in Dash Backend.

Integration Test with Docker and .Net6

Panorama in Flutter

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Diana M.

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.

More from Medium

What is software engineering like at FordLabs?

What’s a day-to-day of a developer relations engineer like?

My First 90 Days at StyleSeat: Meet Ryan Moore, Senior Software Engineer

Software Dev Journey — Jan. 13th to 20th — Taming Discord