Ruby enhancement suggestion

I'm fairly certain this isn't the proper place to suggestion minor
improvements/extensions to the ruby language, but this is something I
constantly find myself wishing was available:

# Extension to ruby class Hash
class Hash
  def join(key_value_sep="=>", pair_sep=",")
    result = ""
    self.each { |k,v| result << k.to_s << key_value_sep << v.to_s <<
pair_sep }
    result.chomp pair_sep
  end
end

I'm sure there's an even cleaner way to do this (and I'd love to see
it!!), but the point is so that I can do something like this:

hash = {}

=> {}

(0..20).each {|i| hash[i] = i+1 }

=> 0..20

hash.join

=>
"16=>17,5=>6,11=>12,0=>1,17=>18,6=>7,12=>13,1=>2,18=>19,7=>8,13=>14,2=>3,19=>20,8=>9,14=>15,3=>4,20=>21,9=>10,15=>16,4=>5,10=>11"

hash.join " maps to ", ", "

=> "16 maps to 17, 5 maps to 6, 11 maps to 12, 0 maps to 1, 17 maps to
18, 6 maps to 7, 12 maps to 13, 1 maps to 2, 18 maps to 19, 7 maps to 8,
13 maps to 14, 2 maps to 3, 19 maps to 20, 8 maps to 9, 14 maps to 15, 3
maps to 4, 20 maps to 21, 9 maps to 10, 15 maps to 16, 4 maps to 5, 10
maps to 11"

Is there currently some easy, builtin way to get this sort of output
that I'm simply unaware of??

···

--
Posted via http://www.ruby-forum.com/\.

Steve Hull wrote:

class Hash
  def join(key_value_sep="=>", pair_sep=",")
    result = ""
    self.each { |k,v| result << k.to_s << key_value_sep << v.to_s <<
pair_sep }
    result.chomp pair_sep
  end
end

Not too hard in ruby:

   h = {:a => 1, :b => 2, :c => 3}

   p h.map{|pair| pair.join("=>")}.join(",")

That's short enough that I wouldn't bother with a method, but if you prefer:

class Hash
   def join(key_value_sep="=>", pair_sep=",")
     map{|pair| pair.join(key_value_sep)}.join(pair_sep)
   end
end

I guess the reason this isn't standard is that it is not very common (?) to treat the keys and values of a hash as strings, regardless of what they really are (note that the fact that keys are symbols is lost in the code above).

···

--
       vjoel : Joel VanderWerf : path berkeley edu : 510 665 3407

Pretty print might suit your needs.

require 'pp'

pp hash

Regards,

Dan

···

-----Original Message-----
From: p.witty@gmail.com [mailto:p.witty@gmail.com]
Sent: Monday, June 01, 2009 7:06 PM
To: ruby-talk ML
Subject: Ruby enhancement suggestion

I'm fairly certain this isn't the proper place to suggestion minor
improvements/extensions to the ruby language, but this is something I
constantly find myself wishing was available:

# Extension to ruby class Hash
class Hash
  def join(key_value_sep="=>", pair_sep=",")
    result = ""
    self.each { |k,v| result << k.to_s << key_value_sep << v.to_s <<
pair_sep }
    result.chomp pair_sep
  end
end

I'm sure there's an even cleaner way to do this (and I'd love to see
it!!), but the point is so that I can do something like this:

>> hash = {}
=> {}
>> (0..20).each {|i| hash[i] = i+1 }
=> 0..20
>> hash.join
=>
"16=>17,5=>6,11=>12,0=>1,17=>18,6=>7,12=>13,1=>2,18=>19,7=>8,13=>14,2=>
3,19=>20,8=>9,14=>15,3=>4,20=>21,9=>10,15=>16,4=>5,10=>11"
>> hash.join " maps to ", ", "
=> "16 maps to 17, 5 maps to 6, 11 maps to 12, 0 maps to 1, 17 maps to
18, 6 maps to 7, 12 maps to 13, 1 maps to 2, 18 maps to 19, 7 maps to
8,
13 maps to 14, 2 maps to 3, 19 maps to 20, 8 maps to 9, 14 maps to 15,
3
maps to 4, 20 maps to 21, 9 maps to 10, 15 maps to 16, 4 maps to 5, 10
maps to 11"

Is there currently some easy, builtin way to get this sort of output
that I'm simply unaware of??

Joel VanderWerf wrote:

   p h.map{|pair| pair.join("=>")}.join(",")

That is indeed nice and compact. Thanks Joel!! That'll do quite nicely
for my needs. :slight_smile:

Daniel Berger wrote:

require 'pp'
pp hash

Thanks Dan! That's a cool feature, but not really what I'm looking for
in the hash.join idea. It is indeed something I'll be using in the
future though. :slight_smile:

···

--
Posted via http://www.ruby-forum.com/\.

Joel VanderWerf wrote:

  p h.map{|pair| pair.join("=>")}.join(",")

That is indeed nice and compact. Thanks Joel!! That'll do quite nicely
for my needs. :slight_smile:

Daniel Berger wrote:

require 'pp'
pp hash

Thanks Dan! That's a cool feature, but not really what I'm looking for
in the hash.join idea. It is indeed something I'll be using in the
future though. :slight_smile:
--

Before the other replies, I was thinking that you just wanted Hash#inspect

hash = {}

=> {}

(0..20).each {|i| hash[i] = i+1 }

=> 0..20

hash

=> {16=>17, 5=>6, 11=>12, 0=>1, 17=>18, 6=>7, 12=>13, 1=>2, 18=>19, 7=>8, 13=>14, 2=>3, 19=>20, 8=>9, 14=>15, 3=>4, 20=>21, 9=>10, 15=>16, 4=>5, 10=>11}

puts hash.inspect

{16=>17, 5=>6, 11=>12, 0=>1, 17=>18, 6=>7, 12=>13, 1=>2, 18=>19, 7=>8, 13=>14, 2=>3, 19=>20, 8=>9, 14=>15, 3=>4, 20=>21, 9=>10, 15=>16, 4=>5, 10=>11}
=> nil

hash.inspect

=> "{16=>17, 5=>6, 11=>12, 0=>1, 17=>18, 6=>7, 12=>13, 1=>2, 18=>19, 7=>8, 13=>14, 2=>3, 19=>20, 8=>9, 14=>15, 3=>4, 20=>21, 9=>10, 15=>16, 4=>5, 10=>11}"

It even keeps the type of the key straight for you.

{:sym => "I'm a symbol", 'string' => "String here!", 1 =>

'Fixnum, too'}.inspect
=> "{1=>\"Fixnum, too\", :sym=>\"I'm a symbol\", \"string\"=>\"String here!\"}"

Of course, you could manage that yourself, too, easily enough with something close to what Joel said:

class Hash
    def join(key_value_sep="=>", pair_sep=",")
        map{|k,v|

[k.inspect,v.inspect].join(key_value_sep)}.join(pair_sep)

      end
  end

=> nil

puts hash.join(" says ", ",\n ")

16 says 17,
  5 says 6,
  11 says 12,
  0 says 1,
  17 says 18,
  6 says 7,
  12 says 13,
  1 says 2,
  18 says 19,
  7 says 8,
  13 says 14,
  2 says 3,
  19 says 20,
  8 says 9,
  14 says 15,
  3 says 4,
  20 says 21,
  9 says 10,
  15 says 16,
  4 says 5,
  10 says 11
=> nil

Note that #inspect is "smarter" because the individual keys and values can do what is right for them. Try the simple #join varieties with values that are themselves Hashes or Arrays.

-Rob

Rob Biedenharn http://agileconsultingllc.com
Rob@AgileConsultingLLC.com

···

On Jun 1, 2009, at 10:01 PM, Steve Hull wrote: