Ruby 获取二维数组中的对角线元素

问题描述 投票:0回答:4

我正在尝试使用 2D ruby 数组解决一些问题,当我进行数组切片时,我的 LOC 减少了很多。例如,

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.次做{一些神奇的事情?}

ruby multidimensional-array
4个回答
19
投票
puts (0..2).collect { |i| array[i][i] }

10
投票

更好的可能是利用 Matrix 库的单行代码:

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

3
投票

Ruby 片段基于 在 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)

2
投票

我正在采纳@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]
]
© www.soinside.com 2019 - 2024. All rights reserved.