2010-03-24 14 views
8

Próbowałem pewnych problemów z moją tablicą 2D ruby, a mój LOC znacznie się zmniejsza, gdy robię cięcie w tablicy. Na przykład:Ruby pobierające elementy ukośne w tablicy 2d

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 

Chcę wiedzieć, czy istnieje sposób na uzyskanie przekątnej plasterka? Powiedzmy, że chcę zacząć od [0,0] i chcę przekątnej plastra 3. Wtedy dostanę elementy od [0,0], [1,1], [2,2] i otrzymam tablicę [1,4,7] na przykład powyżej. Czy istnieje jakiś magiczny, jednolinijkowy kod rubowy, który może to osiągnąć? 3x zrobić {jakieś magiczne rzeczy?}

+1

Prawdopodobnie znasz to, ale 'stawia tablicę [1..2] [1]' jest równoważne do 'puts array [2]', a nie 'puts array [1..2] .map {| arr | arr [1]} '. Nie jestem pewien, czy używanie tablic tablic to właściwy sposób robienia rzeczy, ale nie byłem w stanie zbudować niczego lepszego. –

+0

To była moja intencja. Ale twoja odpowiedź jest nadal bardzo przydatna. Dzięki :) –

Odpowiedz

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

! Rozwiązanie jest tak oczywiste! Dobra robota, chociaż użyłbym array.size zamiast 2, ponieważ długość tablicy może się różnić. –

+0

Awesome :) fajna odpowiedź ... {jakieś magiczne rzeczy?} Jest oczywiste w Ruby – RubyDubee

+0

Przyjemnie jeden potrzebuję 2 zamiast array.size, ponieważ może to być przekątna/częściowa przekątna :) –

4

Lepiej może być jedno-liner, który wykorzystuje bibliotekę matrix:

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

Ruby fragment oparty off Get all the diagonals in a matrix/list of lists in Python

ten ma weź wszystkie przekątne. Tak czy inaczej, chodzi o to, aby umieścić tablicę z różnych stron, tak aby przekątne układały się w rzędach i kolumnach:

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)