2

Suppose I have the hash{ "a" => "b", "c" => "d" } and I would like to transform it into the string "a=b\nc=d".

The solution I've come up with so far is
{ "a" => "b", "c" => "d" }.map { |k, v| k + "=" + v }.join("\n")
Is there a better/more elegant way? For example, can it be done using a single method call?

1
  • 5
    Doing something in a single method call doesn't necessarily mean that it's going to be better or more elegant. Your solution looks very reasonable and compressing it even more probably won't increase readability. Commented Sep 1, 2010 at 21:37

5 Answers 5

5

Any of the proposed solutions will work. Just remember hashes, prior to ruby 1.9.1, are unordered. If you need to keep the order of the elements, remember to sort it first.

{ "a" => "b", "c" => "d" }.sort.map{|k, v| "#{k}=#{v}" }.join("\n")
Sign up to request clarification or add additional context in comments.

1 Comment

In my case, the order didn't matter, but that's good to know nonetheless. Thanks!
4

Not much better but I think this will work:

{ "a" => "b", "c" => "d" }.map { |a| a.join '=' }.join("\n")

Comments

3

Your way is pretty good. I'd make one small change though.

{ "a" => "b", "c" => "d" }.map{|k,v| "#{k}=#{v}" }.join("\n")

Comments

2

All so far proposed solutions look good to me. Here is an 'unchained' one:

{ "a" => "b", "c" => "d" }.inject(""){ |str, kv| str << "%s=%s\n" % kv }

1 Comment

I'll accept this answer because I was specifically curious about something like inject. This was what I was trying to figure out. However, I agree with Adam Byrtek that brevity and elegance doen't always correlate and something like AboutRuby's solution is more readable and is a better fit for actual code.
0

Here are two additional spins on the theme:

str = ''
{ "a" => "b", "c" => "d" }.each_pair{ |n,v| str << "#{n}=#{v}\n" }
str # => "a=b\nc=d\n"

str = ''
{ "a" => "b", "c" => "d" }.each_pair{ |*e| str << e.join('=') << "\n" }
str # => "a=b\nc=d\n"

I'm on 1.9.2 so the hash order is maintained as each_pair() iterates over it.

Inject() could be used instead of appending to the end of the str string, but my brain always has to downshift for a second or two to decode what inject is doing. I prefer appending instead, particularly in the second example because it's free of the "#{}" line-noise.

If you don't want the trailing carriage-return, then @ba has what I'd have gone with, or a quick str.chomp of what I showed.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.