2010-03-24 14 views
8

Estaba intentando algunos problemas con mi matriz de ruby ​​2D y mi LOC se reduce mucho cuando hago un corte de matriz. Así, por ejemplo,Ruby obteniendo los elementos diagonales en un 2d Array

require "test/unit" 

class LibraryTest < Test::Unit::TestCase 

    def test_box 
    array = [[1,2,3,4],[3,4,5,6], [5,6,7,8], [2,3,4,5]] 
    puts array[1][2..3] # 5, 6 
    puts array[1..2][1] # 5, 6, 7, 8 
    end 
end 

quiero saber si hay una manera de conseguir una rebanada diagonal? Digamos que quiero empezar a [0,0] y quiere una rebanada diagonal de 3. Luego obtendría elementos de [0,0], [1,1], [2,2] y voy a tener una serie como [1,4,7] por ejemplo arriba. ¿Hay algún código mágico de rubí de una sola línea que pueda lograr esto? 3x hacer algunas cosas {magia?}

+1

usted probablemente sabe esto, pero 'pone array [1..2] [1]' es equivalente to 'puts array [2]', not 'puts array [1..2] .map {| arr | arr [1]} '. No estoy seguro de si el uso de matrices de matrices de la manera correcta de hacer las cosas, pero no he sido capaz de construir algo mejor. –

+0

Esa era mi intención. Pero tu respuesta sigue siendo muy útil. Gracias :) –

Respuesta

13
puts (0..2).collect { |i| array[i][i] } 
+0

! ¡La solución es tan obvia! Bien hecho, aunque usaría array.size en lugar de 2, ya que la longitud de la matriz puede diferir. –

+0

impresionante :) respuesta fresco ... {algunas cosas magia?} Es obvia en Ruby – RubyDubee

+0

uno de los buenos realmente necesito 2 en lugar de array.size ya que podría ser cualquier rebanada diagonal diagonal/parcial :) –

4

mejor podría haber una sola línea que utiliza la biblioteca de la matriz:

require 'matrix' 
Matrix.rows(array).each(:diagonal).to_a 
2

Rubí fragmento con sede fuera de Get all the diagonals in a matrix/list of lists in Python

Esto es para obtener todas las diagonales De todos modos, la idea es rellenar la matriz de diferentes lados para las diagonales se alinean en las filas y columnas:

arr = [[1, 2, 3, 4], [3, 4, 5, 6], [5, 6, 7, 8], [2, 3, 4, 5]] 

# pad every row from down all the way up, incrementing the padding. 
# so: go through every row, add the corresponding padding it should have. 
# then, grab every column, that’s the end result. 

padding = arr.size - 1 
padded_matrix = [] 

arr.each do |row| 
    inverse_padding = arr.size - padding 
    padded_matrix << ([nil] * inverse_padding) + row + ([nil] * padding) 
    padding -= 1  
end 

padded_matrix.transpose.map(&:compact) 
Cuestiones relacionadas