是否有在 Ruby 中打印可读矩阵的内置方法?
例如
require 'matrix'
m1 = Matrix[[1,2], [3,4]]
print m1
并让它显示
=> 1 2
3 4
在 REPL 中,而不是:
=> Matrix[[1,2][3,4]]
用于矩阵的 Ruby Docs使它看起来应该发生,但这不是我所看到的。我知道编写一个函数来做到这一点是微不足道的,但如果有一种“正确”的方式,我宁愿学习!
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)
我无法让它看起来像文档,所以我为您编写了一个完成相同任务的函数。
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
免责声明:我是 NMatrix 的首席开发人员。
这在 NMatrix 中是微不足道的。做吧matrix.pretty_print
。
列没有整齐地对齐,但这很容易修复,我们希望能对此做出任何贡献。
顺便说一句,很高兴在这里见到一位 VT 同事。=)
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]
好的,我是 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
欢迎任何更正或升级!
这对我有用
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
我刚刚遇到这个问题,还没有看到有人在这里发布它,所以如果它对某人有帮助,我会提出我的解决方案。我知道 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
这是我的答案:
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
来获取格式的漂亮字符串。
没有内置的 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