ruby中的控制台表格式

时间:2016-03-22 13:53:44

标签: ruby console

有没有办法在ruby中输出数组数组作为表?我正在寻找一些从控制台有用的东西,比如powershell的format-table命令。

将传递的数组可能类似于:

a = [[1.23, 5, :bagels], [3.14, 7, :gravel], [8.33, 11, :saturn]]

输出可能是这样的:

-----------------------
| 1.23 |  5 | bagels  |
| 3.14 |  7 | gravel  |
| 8.33 | 11 | saturn  |
-----------------------

4 个答案:

答案 0 :(得分:4)

我接受了sagarpandya82的回答,但这是我更好的实施方式:

class Array
  def to_table
    column_sizes = self.reduce([]) do |lengths, row|
      row.each_with_index.map{|iterand, index| [lengths[index] || 0, iterand.to_s.length].max}
    end
    puts head = '-' * (column_sizes.inject(&:+) + (3 * column_sizes.count) + 1)
    self.each do |row|
      row = row.fill(nil, row.size..(column_sizes.size - 1))
      row = row.each_with_index.map{|v, i| v = v.to_s + ' ' * (column_sizes[i] - v.to_s.length)}
      puts '| ' + row.join(' | ') + ' |'
    end
    puts head
  end
end

答案 1 :(得分:1)

试用Hirb宝石。

此外,有时使用Awesome print会更舒服。

答案 2 :(得分:0)

您可以尝试这样的事情:

a = [[1.23, 5, :bagels], [3.14, 7, :gravel], [8.33, 11, :saturn]]

bar = '-'*(a[0][0].to_s.length + 4 + a[0][1].to_s.length + 3 + a[0][2].to_s.length + 4) 

puts bar
a.each do |i|
  i.each.with_index do |j,k|
    if k == 1 && j < 10
      print "|  #{j} "
    else
      print "| #{j} "
    end
  end
  print '|'
  puts
end
puts bar

返回:

----------------------
| 1.23 |  5 | bagels |
| 3.14 |  7 | gravel |
| 8.33 | 11 | saturn |
----------------------

bar只是估计顶部和底部短划线的长度。通常,此代码检查每个子数组,并在适当的位置打印出|的元素。唯一棘手的一点是每个子阵列的第二个元素。在这里,我们检查它是双位数还是单位数。每种打印格式都不同。

请记住,此代码专门针对您的示例,并做了很多假设。说过它可以很容易地修改来品尝。

答案 3 :(得分:0)

我对@dart-egregious 代码段做了一个小小的改进

class Array
  def to_table(header: true)
    column_sizes = self.reduce([]) do |lengths, row|
      row.each_with_index.map{|iterand, index| [lengths[index] || 0, iterand.to_s.length].max}
    end
    head = '+' + column_sizes.map{|column_size| '-' * (column_size + 2) }.join('+') + '+'
    puts head

    to_print = self.clone
    if (header == true)
      header = to_print.shift
      print_table_data_row(column_sizes, header)
      puts head
    end
    to_print.each{ |row| print_table_data_row(column_sizes, row) }
    puts head
  end

  private
  def print_table_data_row(column_sizes, row)
    row = row.fill(nil, row.size..(column_sizes.size - 1))
    row = row.each_with_index.map{|v, i| v = v.to_s + ' ' * (column_sizes[i] - v.to_s.length)}
    puts '| ' + row.join(' | ') + ' |'
  end
end

使用:

data = [
  ['column 1', 'column 2', 'ciolumn 3'],
  ['row 1 col 2', 'row 1 col 2', 'row 1 col 3'],
  ['row 1 col 2', 'row 1 col 2', 'row 1 col 3']
]

data.to_table
+-------------+-------------+-------------+
| column 1    | column 2    | ciolumn 3   |
+-------------+-------------+-------------+
| row 1 col 2 | row 1 col 2 | row 1 col 3 |
| row 1 col 2 | row 1 col 2 | row 1 col 3 |
+-------------+-------------+-------------+


data.to_table(header: false)
+-------------+-------------+-------------+
| column 1    | column 2    | ciolumn 3   |
| row 1 col 2 | row 1 col 2 | row 1 col 3 |
| row 1 col 2 | row 1 col 2 | row 1 col 3 |
+-------------+-------------+-------------+