Formatting lists in tabular format # Comment: You can iterate through any number of Enumerables in lockstep

e = {
  numbers:   1..10,
  letters:   %w(a b c d e f g h i j),
  notes:     %w(do re mi fa so la ti do),
  phonetic:  %w(alpha bravo charlie delta echo),
  rainbow:   %w(red orange yellow green blue indigo violet)
}

# Titles
puts e.keys.map(&amp;:capitalize).join(" ")

# Values
e.first[1].zip(*e.values[1..-1]) do |layer|
  layer.zip(e.keys) do |node|
    print node[0].to_s.rjust(node[1].length), " "
  end
  puts 
end


This code produces the following output:

Numbers Letters Notes Phonetic Rainbow
      1       a    do    alpha     red 
      2       b    re    bravo  orange 
      3       c    mi  charlie  yellow 
      4       d    fa    delta   green 
      5       e    so     echo    blue 
      6       f    la           indigo 
      7       g    ti           violet 
      8       h    do                  
      9       i                        
     10       j    


I want to tighten up that double loop at the bottom. Can I get rid of the puts that I am using to have each table row on its own line?
You code looks pretty good to me. Some notes:


do |node| and then node[0], node[1]: You should unpack in the block: dp |val1, val2|
Instead of mixing logic with I/O, first build the table string, then print it.


I'd write:

data = {
  numbers:   1..10,
  letters:   %w(a b c d e f g h i j),
  notes:     %w(do re mi fa so la ti do),
  phonetic:  %w(alpha bravo charlie delta echo),
  rainbow:   %w(red orange yellow green blue indigo violet)
}

header = data.keys.map { |k| k.to_s.capitalize }
table = data.values.first.zip(*data.values.drop(1)).map do |row|
  row.zip(header).map do |value, header_name|
    value.to_s.rjust(header_name.size)
  end.join(" ")
end

puts(([header.join(" ")] + table).join("\n"))