Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Flattening hash into string in Ruby

Tags:

ruby

hash

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

like image 723
Fahad Sadah Avatar asked Jun 15 '10 16:06

Fahad Sadah


People also ask

What does Hash do in Ruby?

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.


2 Answers

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"
like image 200
elektronaut Avatar answered Oct 10 '22 00:10

elektronaut


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' 
like image 20
Jörg W Mittag Avatar answered Oct 10 '22 02:10

Jörg W Mittag