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
A Hash is a dictionary-like collection of unique keys and their values. Also called associative arrays, they are similar to Arrays, but where an Array uses integers as its index, a Hash allows you to use any object type. Hashes enumerate their values in the order that the corresponding keys were inserted.
I wouldn't override .flatten
, which is already defined:
Returns a new array that is a one-dimensional flattening of this hash. That is, for every key or value that is an array, extract its elements into the new array. Unlike Array#flatten, this method does not flatten recursively by default. If the optional level argument determines the level of recursion to flatten.
This is simplest way to do it that I'm aware of:
{:a => 100, :b => 200}.map{|k,v| "#{k}=#{v}"}.join('&') # => "a=100&b=200"
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'
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With