Print out 2D array
Asked Answered
B

4

7
array = Array.new(10) { Array.new(10 , 0)}

array.each { |x| print x }

Prints out one single line of ten [0, 0, 0, 0, 0, 0, 0, 0, 0, 0].

If I were to change print to puts, I then get 100 0 down the page.

How do I print out each array on a separate line without the "[]" and ","?

Something like:

0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
Billfish answered 5/12, 2014 at 13:31 Comment(0)
T
11

Suppose:

arr = Array.new(10) { (0..20).to_a.sample(10) }

Then

puts arr.map { |x| x.join(' ') }
1 9 6 15 7 19 18 3 0 12
13 20 18 15 0 3 19 1 14 16
7 16 5 3 12 19 4 9 20 10
6 10 9 1 18 17 7 19 5 15
12 3 8 16 10 5 2 18 20 6
12 9 0 18 2 11 16 8 7 15
8 9 14 19 3 16 6 20 13 17
7 19 16 14 13 6 9 2 3 5
10 17 8 15 11 2 13 14 16 7
14 9 20 17 15 3 4 2 11 19

is not very, er, attractive. For something more pleasing, you could quite easily do something like this:

width = arr.flatten.max.to_s.size+2
  #=> 4
puts arr.map { |a| a.map { |i| i.to_s.rjust(width) }.join }
   1   9   6  15   7  19  18   3   0  12
  13  20  18  15   0   3  19   1  14  16
   7  16   5   3  12  19   4   9  20  10
   6  10   9   1  18  17   7  19   5  15
  12   3   8  16  10   5   2  18  20   6
  12   9   0  18   2  11  16   8   7  15
   8   9  14  19   3  16   6  20  13  17
   7  19  16  14  13   6   9   2   3   5
  10  17   8  15  11   2  13  14  16   7
  14   9  20  17  15   3   4   2  11  19

If you have too many columns to display on the screen you can do this:

puts arr.map { |a| a.map { |i| i.to_s.rjust(width) }.join.tinyfy }
    1   9   6  15   7  19  18   3   0  12
   13  20  18  15   0   3  19   1  14  16
    7  16   5   3  12  19   4   9  20  10
    6  10   9   1  18  17   7  19   5  15
   12   3   8  16  10   5   2  18  20   6
   12   9   0  18   2  11  16   8   7  15
    8   9  14  19   3  16   6  20  13  17
    7  19  16  14  13   6   9   2   3   5
   10  17   8  15  11   2  13  14  16   7
   14   9  20  17  15   3   4   2  11  19
Technocracy answered 5/12, 2014 at 19:55 Comment(6)
I like the fact that you adjusted the columns.Mcleroy
The method tinyfy seems very useful.Taenia
The tinyfy method does seem very useful. Where is this implemented? I cannot find any reference to it. For the sake of this answer I think it might be useful to explain where this method is since it does not seem to be a built in String methodMcleroy
@engineersmnky,tinyfy was introduced in Ruby 2.1.5 (at this writing, the latest stable version), but the most recent docs are for v. 2.1.4. The 2.1.5 docs should be released shortly.Technocracy
@engineersmnky: it makes a string be printed in a smaller font. Useful for displaying large amounts of data.Chamkis
@SergioTulentsev thank you I certainly understood what it's purpose was just could not find a documented method for it anywhere.Mcleroy
S
6

Try join:

array.each { |x|
 puts x.join(" ")
}
# prints:
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
Singletree answered 5/12, 2014 at 13:38 Comment(1)
alternatively: puts array.map { |x| x.join(' ') }Monograph
P
5

Print a 2-dimensional array with spacing between columns

Accepts a 2d array of objects that have a to_s method (strings integers floats and booleans..) and an optional margin width integer.

Update: It now works with arrays of varying lengths.

def print_table(table, margin_width = 2)
  # the margin_width is the spaces between columns (use at least 1)

  column_widths = []
  table.each do |row|
    row.each.with_index do |cell, column_num|
      column_widths[column_num] = [column_widths[column_num] || 0, cell.to_s.size].max
    end
  end

  puts (table.collect do |row|
    row.collect.with_index do |cell, column_num|
      cell.to_s.ljust(column_widths[column_num] + margin_width)
    end.join
  end)
end

Note: the parenthesis after the puts statement is required so table.collect and the do end block are not passed as two separate parameters to the puts method.

Example table

my_table = [
  ["1", "Animal", "Dog", "1"],
  [1, "Animal", "Cat", "2"],
  [1, "Animal", "Bird", "3"],
  [2, "Place", "USA", "1"],
  [2.5, "Place", "Other", "2"],
  [3, "Color", "Red"],
  [3, "Color", "Blue", "b"],
  [3, "Some more color", "Orange", "c"],
  [4.7, "Age", "Young", "a"],
  [4, "Age", "Middle", "b"],
  [4, "Age", "Old", "c"],
  [5, "Alive"],
  [],
  [5, "Alive", false, "n"]
]

print_table my_table

Prints:

1    Animal           Dog     1  
1    Animal           Cat     2  
1    Animal           Bird    3  
2    Place            USA     1  
2.5  Place            Other   2  
3    Color            Red     
3    Color            Blue    b  
3    Some more color  Orange  c  
4.7  Age              Young   a  
4    Age              Middle  b  
4    Age              Old     c  
5    Alive            

5    Alive            false   n 

(Not colored. The coloring above was added by StackOverflow.)

Pacifism answered 22/4, 2018 at 20:40 Comment(4)
This is awesome! Way better than any other answer.Shanan
do you have a version that allows for arrays of different sizes?Tetrastichous
transpose seems to be there issue here. You'd probably need to either pad your arrays with nil values to be the same length or rewrite that chunk of code to avoid using transpose. Maybe I'll get around to fixing it later.Pacifism
@Tetrastichous I've updated the solution to support arrays of varying sizes.Pacifism
S
2

You may want to write your own method to do it. Something like:

def array_2D_print array
    array.each do |arr|
        arr.each do |item|
            print "#{item} "
        end
        print "\n"
    end
end

If you only use this once in your code, you might also consider not creating any method:

array.each do |arr|
    arr.each do |item|
        print "#{item} "
    end
    print "\n"
end

This solution has the advantage of being easier to modify than other alternatives, to match what you want to print.

Semaphore answered 5/12, 2014 at 13:41 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.