tags:

views:

77

answers:

5

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?

+4  A: 

Not much better but I think this will work:

{ "a" => "b", "c" => "d" }.map { |a| a.join '=' }.join("\n")
ba
+3  A: 

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

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

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")
Chubas
In my case, the order didn't matter, but that's good to know nonetheless. Thanks!
Ray
+2  A: 

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 }
steenslag
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.
Ray
A: 

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.

Greg