Modulo Operator % in conditional block


#1

HI all,
I’m trying to print out a series of arrays as columns and found the below stack overflow thread on the subject: https://stackoverflow.com/questions/11108011/is-there-a-built-in-method-or-gem-that-can-print-a-ruby-array-in-columns
Stack Overflow
Is there a built-in method or gem that can print a Ruby array in c…
I have a large Ruby array that I would like to print in columns, just like the default output of Unix’ ‘ls’ command (on OS X, at least). Is there a gem or built-in method that can do this? I am a…

my question is in the answer
irb> cols = a.each_slice((a.size+2)/3).to_a
=> [[0, 1, 2, 3, 4, 5, 6], [7, 8, 9, 10, 11, 12, 13], [14, 15, 16, 17, 18]]
irb> cols.first.zip( *cols[1…-1] ).each{|row| puts row.map{|e| e ? ‘%5d’ % e : ’ '}.join(" ") }
0 7 14
1 8 15
2 9 16
3 10 17
4 11 18
5 12
6 13
what does *cols do? and also what is the conditional in the block attached to row.map doing?
what does ‘%5d’ % e do?


#2

Going through your questions in reverse:

  1. what does ‘%5d’ % e do?
    It uses idiosyncratic Ruby to place a number at the end of a string of 5 characters, with spaces preceding the number, (using the last one or more characters for the digits of the number). Try it, with:
    $ puts ‘%5d’ % 7
    $ puts ‘%5d’ % 17
    [notice how the '7’s align vertically when you run those two different versions]

  2. what is the conditional in the block attached to row.map doing?
    The e ? ‘%5d’ % e : ’ ’ conditional is taking each element ‘e’ considered by the block it is placed within (which, in the example you copied, are each of the numbers from the array(s) provided).
    e ? is testing if e exists.
    if e exists, then the %5d’ % e is run (creating a 5 character string, comprised of spaces and the number, as described above).
    if e does not exist then the ' ' is run; a string of 5 blank spaces is created.

  3. what does *cols do?
    cols is defined in the line cols = a.each_slice((a.size+2)/3).to_a
    It takes array a (defined earlier in the example you reference, but not copied by you) and slices this array into a number of arrays. Looking at the simpler example just prior to the bit you copied may help you to understand how this works, plus this illustrates the basic concept.