2012-04-29 21 views
9

¿Existe una forma integrada de imprimir una matriz legible en Ruby?Impresión de una matriz legible en Ruby

Por ejemplo

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

y tienen que mostrar

=> 1 2 
    3 4 

en el REPL en lugar de:

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

El Rubí Docs para matrix hacer que parezca que eso es lo que debería mostrar suceder, pero eso no es lo que estoy viendo. Sé que sería trivial escribir una función para hacer esto, pero si hay una forma "correcta", preferiría aprender.

Respuesta

8

Se podría convertirla en una matriz:

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

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

EDIT:

Aquí es una "libre punto" versión:

puts m1.to_a.map(&:inspect) 
1

Usted puede utilizar el método each_slice combinado con la column_size método.

m1.each_slice(m1.column_size) {|r| p r } 
=> [1,2] 
    [3,4] 
3

No pude conseguir que se vea como la documentación, así que escribí una función para usted que realiza la misma tarea.

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 
3

Descargo de responsabilidad: Soy el desarrollador principal de NMatrix.

Es trivial en NMatrix. Solo haz matrix.pretty_print.

Las columnas no están alineadas limpiamente, pero eso sería fácil de arreglar y nos encantaría cualquier contribución a tal efecto.

Por cierto, es agradable ver a un compañero de la persona VT aquí. =)

+2

Definitivamente revisaré SciRuby/NMatrix. Soy nuevo en Ruby, así que esperaba usarlo para un proyecto de posgrado para aprender un poco más. El hecho de que la matriz estándar en Ruby sea inmutable me provocó el abandono de C#. No sabía si libs de terceros volaría con mi profesor y estaba en una crisis. Además, nos graduamos el mismo año en VT, fue genial ver que estás en UT. Yo era Math/CS y podría estar interesado en prestarle a su proyecto, le enviaré un mensaje. – vpiTriumph

1

Ok, soy un novato total en la programación de ruby. Solo estoy haciendo mis primeras incursiones, pero sucede que tengo el mismo problema e hice este acercamiento rápido y sucio. Funciona con la biblioteca estándar de Matrix e imprimirá columnas formateadas con el mismo tamaño.

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 

Cualquier corrección o actualización ¡Bienvenido!

1

Esto es trabajo para mí

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 
0

Aquí está mi respuesta:

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" 

Usted podría utilizar Matrix#to_pretty_s para obtener una cadena bastante para el formato.

0

No hay una forma incorporada de Ruby de hacer esto. Sin embargo, he creado un Módulo que se puede incluir en Matrix que incluye un método readable. Puede encontrar este código here, pero también está en el siguiente bloque de código.

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 
Cuestiones relacionadas