Forum: Ruby convert 2D array to cute text table with | pipes ?

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.
Aafa8848c4b764f080b1b31a51eab73d?d=identicon&s=25 Phlip (Guest)
on 2009-06-02 18:45
(Received via mailing list)
Ruboids:

I have only started googling I will report back here what I find or
write.

Does anyone have a code snippet which reads a 2D array and outputs a
cute
formatted text table, like this?

       |   concept       | frobs |  zones |
       | Unruly Pygmy    |    6  |  10001 |
       | Renonymize      |    4  |   9999 |
       | Opramatic       |    4  |  10001 |
       | El Pollo Psycho |    4  |  10002 |
       | Mouse Guard     |    4  |  10003 |
       | layuhponit      |    4  |  10004 |

Please notice I'm not asking how to format text with sprintf('%*i') etc.
I'm
asking if anyone has solved this problem in some cute generic way that
makes for
a good Ruby exercise.
753dcb78b3a3651127665da4bed3c782?d=identicon&s=25 Brian Candler (candlerb)
on 2009-06-02 19:16
Have a look at Ruport's text table rendering code
Aafa8848c4b764f080b1b31a51eab73d?d=identicon&s=25 Phlip (Guest)
on 2009-06-02 19:46
(Received via mailing list)
Brian Candler wrote:

> Have a look at Ruport's text table rendering code

txbut - I should'a made clear I have no mandate to install a whole new
library.
Does it contain a snippet like this?

   def row_to_pipes(row, widths)
     widths = widths.dup

     return ' ' + row.map{|c|
           case c
             when Fixnum
               c.to_s.rjust(widths.shift)
             else
               c.to_s.ljust(widths.shift)
           end
         }.join(' | ') + ' '
   end

   def table_to_pipes(table)
     widths = (0 ... table.first.length).map do |x|
                table.sort_by{|q| q[x].to_s.length }.last[x].to_s.length
              end

     table.map{|r| row_to_pipes(r, widths) }.join("\n")
   end

   test 'array to pipes' do
     assert_equal ' a | b  | c ', row_to_pipes(%w(a b c), [1, 2, 1])
   end

   test 'table to pipes' do
     assert_equal " a | bb | c \n d |  2 | f ",
       table_to_pipes([%w(a bb c), ['d', 2, 'f']])
   end

Understand I would never write code this sloppy in production. Really!
I'm just
letting it out here so if anyone can think of a way to refactor it and
DRY it
up, we could make a little good-code experiment out of it.

It provides the effect I'm after:

     puts table_to_pipes( [['__concept__', '__frobs', '__zones'],
                           [ 'Unruly Pygmy',      6,     10001 ],
                           [ 'Renonymize',        4,      9999 ],
                           [ 'Opramatic',         4,     10001 ],
                           [ 'El Pollo Psycho',   4,     10002 ],
                           [ 'Mouse Guard',       4,     10003 ],
                           [ 'layuhponit',        4,     10004 ]] )

  __concept__     | __frobs | __zones
  Unruly Pygmy    |       6 |   10001
  Renonymize      |       4 |    9999
  Opramatic       |       4 |   10001
  El Pollo Psycho |       4 |   10002
  Mouse Guard     |       4 |   10003
  layuhponit      |       4 |   10004
134ea397777886d6f0aa992672a50eaa?d=identicon&s=25 Mark Thomas (Guest)
on 2009-06-03 14:26
(Received via mailing list)
I wrote an implementation using the Matrix class, but it didn't really
make it any shorter/cleaner/DRYer. I think your code is fairly DRY
already. The only thing I might suggest is extracting your
justification, e.g.

def justify(obj,w)
  case obj
  when Fixnum
    obj.to_s.rjust(w)
  else
    obj.to_s.ljust(w)
  end
end
This topic is locked and can not be replied to.