在一个二维数组中获取对角线元素的Ruby代码

10

我正在尝试一些关于我的2D Ruby数组的问题,当我进行数组切片时,代码行数大大减少。例如:

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.times do {一些魔法的东西?}

1
你可能已经知道了,但是 puts array[1..2][1] 等同于 puts array[2],而不是 puts array[1..2].map{|arr| arr[1]}。我不确定使用数组的数组是否是正确的做法,但我还没有能够构建出更好的东西。 - Andrew Grimm
那是我的意图。但是你的答案仍然非常有用。谢谢 :) - Kannan Ekanath
4个回答

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

2
解决方案非常明显!干得好,尽管我会使用array.size代替2,因为数组长度可能不同。 - Ryan Bigg
棒极了 :) 酷毙了的答案... 在Ruby中 {一些神奇的东西?} 很明显。 - RubyDubee
其实很不错,我需要的是2而不是array.size,因为它可以是任何对角线/部分对角线切片 :) - Kannan Ekanath
2 只适用于 3x3 矩阵:对于其他大小的矩阵,请使用 array.size-1 替代。 - Marco Lackovic

9
更好的方法可能是使用Matrix库的一行代码实现:
require 'matrix'
Matrix.rows(array).each(:diagonal).to_a

3

基于Python中获取矩阵/列表中所有对角线的代码片段的Ruby代码。

这是为了获取所有对角线。无论如何,思路是从不同的方向填充数组,使对角线在行和列上对齐:

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)

1
我将采用@Shai的答案并提出更多的功能性建议。
首先,我们需要初始化数组:
arr = [[1, 2, 3, 4], [3, 4, 5, 6], [5, 6, 7, 8], [2, 3, 4, 5]]

然后我们准备用作填充的数组:

padding = [*0..(arr.length - 1)].map { |i| [nil] * i }
=> [[], [nil], [nil, nil], [nil, nil, nil]]

然后我们将填充应用于数组。如果您要获取向下或向上对角线,则取决于填充的第一次使用或第二次使用。

padded = padding.reverse.zip(arr).zip(padding).map(&:flatten)
=> [[nil, nil, nil, 1, 2, 3, 4], [nil, nil, 3, 4, 5, 6, nil], [nil, 5, 6, 7, 8, nil, nil], [2, 3, 4, 5, nil, nil, nil]]

然后我们按照@Shai的解决方案进行转置:
padded.transpose.map(&:compact)
=> [[2], [5, 3], [3, 6, 4], [1, 4, 7, 5], [2, 5, 8], [3, 6], [4]]

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接