11

是否有在 Ruby 中打印可读矩阵的内置方法?

例如

require 'matrix'
m1 = Matrix[[1,2], [3,4]]
print m1

并让它显示

=> 1 2
   3 4

在 REPL 中,而不是:

=> Matrix[[1,2][3,4]]

用于矩阵的 Ruby Docs使它看起来应该发生,但这不是我所看到的。我知道编写一个函数来做到这一点是微不足道的,但如果有一种“正确”的方式,我宁愿学习!

4

9 回答 9

14

You could convert it to an array:

m1.to_a.each {|r| puts r.inspect}

=> [1, 2]
   [3, 4]

EDIT:

Here is a "point free" version:

puts m1.to_a.map(&:inspect)
于 2012-04-29T06:15:04.243 回答
6

我无法让它看起来像文档,所以我为您编写了一个完成相同任务的函数。

require 'matrix'

m1 = Matrix[[1,2],[3,4],[5,6]]

class Matrix
  def to_readable
    i = 0
    self.each do |number|
      print number.to_s + " "
      i+= 1
      if i == self.column_size
        print "\n"
        i = 0
      end
    end
  end
end

m1.to_readable

=> 1 2 
   3 4 
   5 6 
于 2012-04-29T07:18:43.947 回答
3

免责声明:我是 NMatrix 的首席开发人员。

这在 NMatrix 中是微不足道的。做吧matrix.pretty_print

列没有整齐地对齐,但这很容易修复,我们希望能对此做出任何贡献。

顺便说一句,很高兴在这里见到一位 VT 同事。=)

于 2012-05-04T19:07:49.943 回答
1

You can use the each_slice method combined with the column_size method.

m1.each_slice(m1.column_size) {|r| p r }
=> [1,2]
   [3,4]
于 2012-04-29T06:19:47.550 回答
1

好的,我是 ruby​​ 编程的新手。我刚刚开始我的第一次入侵,但碰巧我遇到了同样的问题并采取了这种快速'n'dirty的方法。与标准 Matrix 库一起使用,并将打印具有相同大小格式的列。

class Matrix
  def to_readable
   column_counter = 0
   columns_arrays = []
   while column_counter < self.column_size
     maximum_length = 0
     self.column(column_counter).each do |column_element|# Get maximal size
       length = column_element.to_s.size
       if length > maximal_length
         maximum_length = length
       end
     end # now we've got the maximum size
     column_array = []
     self.column(column_counter).each do |column_element| # Add needed spaces to equalize each column
      element_string = column_element.to_s
      element_size = element_string.size
      space_needed = maximal_length - element_size +1
      if space_needed > 0
        space_needed.times {element_string.prepend " "}
        if column_counter == 0
          element_string.prepend "["
        else
          element_string.prepend ","
        end  
      end
      column_array << element_string
    end
    columns_arrays << column_array # Now columns contains equal size strings
    column_counter += 1
  end
  row_counter = 0
  while row_counter < self.row_size
    columns_arrays.each do |column|
      element = column[row_counter]
      print element #Each column yield the correspondant row in order
    end
    print "]\n"
    row_counter += 1
  end
 end
end

欢迎任何更正或升级!

于 2013-11-19T21:18:59.753 回答
1

这对我有用

require 'matrix'

class Matrix

  def print
    matrix = self.to_a
    field_size = matrix.flatten.collect{|i|i.to_s.size}.max
    matrix.each do |row|
      puts (row.collect{|i| ' ' * (field_size - i.to_s.size) + i.to_s}).join('  ')    
    end
  end

end

m = Matrix[[1,23,3],[123,64.5, 2],[0,0,0]]
m.print
于 2015-07-05T22:14:46.907 回答
0

我刚刚遇到这个问题,还没有看到有人在这里发布它,所以如果它对某人有帮助,我会提出我的解决方案。我知道 2 个 for 循环不是最好的主意,但对于较小的矩阵来说应该没问题,它打印得很漂亮,而且你想要的样子,也不需要使用 require 'matrix' 或 'pp'

matrix = Array.new(numRows) { Array.new(numCols) { arrToTakeValuesFrom.sample } }

for i in 0..numRows-1 do
  for j in 0..numCols-1 do
    print " #{matrix[i][j]} "
  end
  puts ""
end
于 2021-03-09T16:06:14.493 回答
0

这是我的答案:

require 'matrix'

class Matrix
    def to_pretty_s
        s = ""
        i = 0
        while i < self.column_size
            s += "\n" if i != 0
            j = 0
            while j < self.row_size
                s += ' ' if j != 0
                s += self.element(i, j).to_s
                j += 1
            end
            i += 1
        end
        s
    end
end

m = Matrix[[0, 3], [3, 4]]

puts m # same as 'puts m.to_s'
# Matrix[[0, 3], [3, 4]]

puts m.to_pretty_s
# 0 3
# 3 4

p m.to_pretty_s
# "0 3\n3 4"

您可以使用Matrix#to_pretty_s来获取格式的漂亮字符串。

于 2015-09-15T13:28:11.747 回答
0

没有内置的 Ruby 方法可以做到这一点。但是,我创建了一个可以包含在包含方法的 Matrix 中的模块readable。您可以在此处找到此代码,但它也在以下代码块中。

require 'matrix'

module ReadableArrays
    def readable(factor: 1, method: :rjust)
        repr = to_a.map { |row|
            row.map(&:inspect)
        }

        column_widths = repr.transpose.map { |col|
            col.map(&:size).max + factor
        }

        res = ""
        repr.each { |row|
            row.each_with_index { |el, j|
                res += el.send method, column_widths[j]
            }
            res += "\n"
        }
        res.chomp
    end
end

## example usage ##
class Matrix
    include ReadableArrays
end
class Array
    include ReadableArrays
end

arr = [[1, 20, 3], [20, 3, 19], [-32, 3, 5]]
mat = Matrix[*arr]

p arr
#=> [[1, 20, 3], [20, 3, 19], [-2, 3, 5]]
p mat
#=> Matrix[[1, 20, 3], [20, 3, 19], [-2, 3, 5]]

puts arr.readable
#=>
#    1 20  3
#   20  3 19
#  -32  3  5
puts mat.readable
#=>
#    1 20  3
#   20  3 19
#  -32  3  5
puts mat.readable(method: :ljust)
#=>
# 1   20 3
# 20  3  19
# -32 3  5
puts mat.readable(method: :center)
#=>
#  1  20  3
#  20  3 19
# -32  3  5
于 2018-01-20T22:31:40.407 回答