Welcome to the Treehouse Community

The Treehouse Community is a meeting place for developers, designers, and programmers of all backgrounds and skill levels to get support. Collaborate here on code errors or bugs that you need feedback on, or asking for an extra set of eyes on your latest project. Join thousands of Treehouse students and alumni in the community today. (Note: Only Treehouse students can comment or ask questions, but non-students are welcome to browse our conversations.)

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and a supportive community. Start your free trial today.

Ruby

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
    else
      case opt
      when 0
        h[k.to_sym] = v 
      when 1 
        h[k.to_s] = v
      end 
    end
  end
  return h
end

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.

Rich

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

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")
  end

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

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

Rich,

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.