Forum: Ruby Ruby enhancement suggestion

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
89992299997cb05046d970aa3d867ff8?d=identicon&s=25 Steve Hull (sdhull)
on 2009-06-02 03:05
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??
47b1910084592eb77a032bc7d8d1a84e?d=identicon&s=25 Joel VanderWerf (Guest)
on 2009-06-02 03:33
(Received via mailing list)
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).
Aee77dba395ece0a04c688b05b07cd63?d=identicon&s=25 Daniel Berger (djberg96)
on 2009-06-02 03:35
(Received via mailing list)
> # Extension to ruby class Hash
> it!!), but the point is so that I can do something like this:
> => "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??

Pretty print might suit your needs.

require 'pp'

pp hash

Regards,

Dan
89992299997cb05046d970aa3d867ff8?d=identicon&s=25 Steve Hull (sdhull)
on 2009-06-02 04:01
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.   :)

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.  :)
Ef3aa7f7e577ea8cd620462724ddf73b?d=identicon&s=25 Rob Biedenharn (Guest)
on 2009-06-02 04:29
(Received via mailing list)
On Jun 1, 2009, at 10:01 PM, Steve Hull wrote:

>
> 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.  :)
> --


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

irb> hash = {}
=> {}
irb> (0..20).each {|i| hash[i] = i+1 }
=> 0..20
irb> 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}
irb> 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
irb> 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.

irb> {: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:

irb> class Hash
irb>     def join(key_value_sep="=>", pair_sep=",")
irb>         map{|k,v|
[k.inspect,v.inspect].join(key_value_sep)}.join(pair_sep)
irb>       end
irb>   end
=> nil
irb> 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
This topic is locked and can not be replied to.