0

多次元配列のベクトルの形状を知っているので、どうすればそれを1次元の新しいベクトルに変換できますか(多次元配列を平坦化することによって)?

たとえば、次の配列を考えます。

arr = [
  [
    [ nil, nil ],
    [ nil, nil ],
    [ nil, nil ]
  ],
  [
    [ nil, nil ],
    [ nil, nil ],
    [ nil, nil ]
  ]
]

arr[0][0][0] = "A"
arr[1][0][1] = "B"

arr # =>
[
  [
    [ "A", nil ],
    [ nil, nil ],
    [ nil, nil ]
  ],
  [
    [ nil, "B" ],
    [ nil, nil ],
    [ nil, nil ]
  ]
]

...ここで、はベクトルAの起点とB終点です。書ける:

shape  = [2, 3, 2]
vector = [1, 0, 1]

これから、平坦化すると仮定するとarr、ベクトルをどのように変換できますか?言い換えれば、この3次元のベクトルを1次元の新しいベクトルに変換するにはどうすればよいでしょうか。

ベクトルの原点は配列の最初の座標でもあるため、これは特殊なケースです。したがって、次の結果を見つけることができます。

arr.flatten.index("B") # => 7

2D配列を使用した別の例を次に示します。

arr = [
  [ "A", nil ],
  [ "B", nil ],
  [ nil, nil ],
  [ nil, nil ],
  [ nil, nil ]
]

私たちはこれを書くことができます:

shape  = [2, 5]
vector = [1, 0]

そして、もう一度、

arr.flatten.index("B") # => 2

しかし、これは負のベクトルを使用した、より複雑な例です。

arr = [
  [ "B", nil ],
  [ "A", nil ],
  [ nil, nil ],
  [ nil, nil ],
  [ nil, nil ]
]

shape  = [2, 5]
vector = [-1, 0]

次のメソッドはどのように書くことができますか?

vector2index(shape, vector) # => -2

1D配列の例(単純):

arr = [ nil, "B", nil, nil, "A", nil, nil ]

shape  = [7]
vector = [-3]
vector2index(shape, vector) # => -3

任意の次元の配列からベクトルをフラット化する簡単な方法はありますか?ありがとう。

4

1 に答える 1

0

まず、配列の最初の要素がX軸用、2番目(Y軸用)、3番目(Z軸用)であると仮定すると、2番目と3番目の例に誤りがあります。3番目の例は

shape  = [2,5]
vector = [0,-1]
vector2index(shape, vector) # => -2

また、配列の最初の要素がY軸用で、2番目の要素がX軸用の場合、2番目と3番目の例は正しいですが、最初の例は間違っています。

私がその考えを正しく理解しているなら、最初の例では、乗算vector[1]してshape[0]、乗算vector[2]してからshape[0]*shape[1]、3つの要素の合計を計算する必要があります。通常、0番目の要素を乗算する必要はなく、n番目の要素をに乗算する必要がありshape[0]*shape[1]*...*shape[n-1]ます。

次のように実装できます。

vector.each_with_index.map { 
  |v, i| i == 0? v: v * shape[0..i-1].inject(:*) 
}.inject(:+)

更新 質問を更新すると、より明確になります。Rubyのインデックスの順序を維持したい場合は、配列shapeとの両方を逆にする必要がありますvector

vector.reverse.each_with_index.map { 
  |v, i| i == 0? v: v * shape[0..i-1].reverse.inject(:*) 
}.inject(:+)
于 2012-05-01T00:59:34.687 に答える