2010-03-24 4 views
8

Я пытался решить некоторые проблемы с моим 2D-рубиновым массивом, и мой LOC значительно сокращает время, когда я занимаюсь массивом массивов. Так, например,Ruby, получая диагональные элементы в массиве 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 

Я хочу знать, есть ли способ получить диагональный срез? Предположим, что я хочу начать с [0,0] и хочу диагональный срез из 3. Тогда я бы получил элементы из [0,0], [1,1], [2,2], и я получу массив вроде [1,4,7], например, выше. Есть ли какой-нибудь волшебный однострочный рубиновый код, который может это сделать? 3 × делать {некоторые магические вещи?}

+1

Вы, наверное, знаете это, но 'помещает массив [1..2] [1]' эквивалентно to 'puts array [2]', а не 'puts array [1..2] .map {| arr | обр [1]} '. Я не уверен, что с помощью массивов массивов это правильный способ делать вещи, но я не смог построить ничего лучше. –

+0

Это было мое намерение. Но ваш ответ по-прежнему очень полезен. Спасибо :) –

ответ

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

! Решение настолько очевидно! Хорошо сделано, хотя я бы использовал array.size вместо 2, так как длина массива может отличаться. –

+0

Awesome :) классный ответ ... {какой-то волшебный материал?} Очевиден в Ruby – RubyDubee

+0

Приятный на самом деле мне нужен 2 вместо array.size, поскольку это может быть любой диагональный/частичный диагональный срез :) –

4

Лучше может быть один лайнер, который использует библиотеку Matrix:

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

Рубин фрагмент основан офф Get all the diagonals in a matrix/list of lists in Python

Это должен получить все диагонали. Во всяком случае, идея состоит в том, чтобы дополнить массив с разных сторон так диагонали выравнивают в строках и столбцах:

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) 
Смежные вопросы