Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial


Ruby Foundations > Hashes > Extra Credit - submission from a newbie

Hello all. I'm currently try to teach myself programming and enjoy the content presented by Treehouse. Since you can't really learn anything by being isolated I thought I would share the my attempt at the Extra Credit in the Ruby Foundations Course under Hashes.

Now that we know how hashes work, write a function that converts hashes with string keys in to hashes with symbols as keys. The function should work recursively.

Here's what I came up with:

def convertkey(hsh, opt)
  h = {}
  hsh.each do |k,v|
    if k.class == Fixnum
      h[k] = v
      case opt
      when 0
        h[k.to_sym] = v 
      when 1 
        h[k.to_s] = v
  return h

After putting the method in IRB I would create a hash:

tst = {"one" => "First", :two => "Second", 3 => "Third"}

And then I would change the keys using my option parameter: 0 for symbols, and 1 for strings.

tst = convertkey(tst, 0)

Thanks for checking it out!

2 Answers

Hi Josh

Well done for doing the extra credit. I managed to miss those out ;-) I am not a Ruby expert either but I'll give a few comments.

1) I would make the function do one thing only. In this case just string keys to symbol keys. I would then call the function symbolize_hash_keys - that way a user of your function would have a good idea what it does and, bonus, you can simplify the code which means fewer bugs.

2) The Ruby idiom is to leave off implicit return values at the end of methods, following this convention the last line would be just, h

3) They have actually asked for a very difficult thing. Which is a recursive problem, so you would have to handle: {'one'=>{'two'=>{'three' =>"3"}}. My solution doesn't solve this problem either.

I've put my solution at the bottom in case you wanted to refactor yours before looking at my solution - I've used RSpec tests but equally could have been minitest. My solution can be refacted further using the ? operator.


def symbolize_hash_keys(hsh)
  hsh.map do |key, value|
    case key
      when String then { key.to_sym => value }
      else { key => value }

describe "symbolize_hash_keys" do
  it "string keys to_symbol" do
    tst = {"one" => "First"}
    output = symbolize_hash_keys(tst)
    expect(output).to include(:one => "First")

  it "symbol keys unchanged" do
    tst = {:one => "First"}
    output = symbolize_hash_keys(tst)
    expect(output).to include(:one => "First")

  it "Finxnum unchanged" do
    tst = {1 => "First"}
    output = symbolize_hash_keys(tst)
    expect(output).to include(1 => "First")


Thanks for the feedback! I have not looked at your solution yet. I realize now that I had misunderstood the meaning of 'recursively.' I just did some (quick) reading on recursion in Ruby. I'll carve out some time to make another attempt. I still need to read up on testing. I get the concept but don't really know how to write tests yet so I'm looking forward to spending some time in those lessons that are available.

Again, I appreciate the positive response and constructive criticism.