tags:

views:

70

answers:

5

Is there a way to flatten a hash into a string, with optional delimiters between keys and values, and key/value pairs?

For example, print {:a => :b, :c => :d}.flatten('=','&') should print a=b&c=d

I wrote some code to do this, but I was wondering if there was a neater way:

class Hash
  def flatten(keyvaldelimiter, entrydelimiter)
    string = ""
    self.each do
      |key, value|
      key = "#{entrydelimiter}#{key}" if string != "" #nasty hack
      string += "#{key}#{keyvaldelimiter}#{value}"  
    end
    return string
  end
end

print {:a => :b, :c => :d}.flatten('=','&') #=> 'c=d&a=b'

Thanks

+4  A: 

Well, you could do it with standard methods and arrays:

class Hash
  def flatten(keyvaldelimiter, entrydelimiter)
    self.map { |k, v| "#{k}#{keyvaldelimiter}#{v}" }.join(entrydelimiter)
  end
end

You might also be interested in the Rails to_query method.

Also, obviously, you can write "#{k}#{keyvaldelimiter}#{v}" as k.to_s + keyvaldelimiter + v.to_s...

Amadan
Or `[k,v].join(keyvaldelimiter)`.
dvyjones
+1  A: 

Not sure if there's a built-in way, but here's some shorter code:

class Hash
  def flatten(kvdelim='', entrydelim='')
    self.inject([]) { |a, b| a << b.join(kvdelim) }.join(entrydelim)
  end
end

puts ({ :a => :b, :c => :d }).flatten('=', '&') # => a=b&c=d
dvyjones
+3  A: 
elektronaut
This is neater than Amadan's. Thanks, you're the new accepted
fahadsadah
You can further simplify this. See my answer for details. The gist is to replace `|k, v|` with `|e|` which makes `e` an array that you can call `e.join('=')` on.
Jörg W Mittag
+2  A: 

Slight variation of @elektronaut's version:

You can actually put just an |e| there instead of |k, v| in which case e is an array of two elements and you can call e.join('='). Altogether you have something like

class Hash
  def join(keyvaldelim=$,, entrydelim=$,) # $, is the global default delimiter
    map {|e| e.join(keyvaldelim) }.join(entrydelim)
  end
end

{a: 100, b: 200}.join('=', '&') # I love showing off the new Ruby 1.9 Hash syntax
# => 'a=100&b=200'
Jörg W Mittag
A: 

What about getting it in JSON format. That way the format is clear.

There are lots of JSON tools for ruby. Never tried them, though. But the output will then of course slide into javascript, etc easier. Likely one line.

The big savings, though would be in documentation, in that you will need much less.

Tom Andersen