将索引转换为坐标

时间:2012-05-08 17:17:16

标签: ruby arrays math multidimensional-array coordinates

当我有一个数组(1D,2D,3D或更多维度)时,我希望能够将索引(从这个展平数组)转换为其坐标。

例如,考虑* square:

3D阵列([2,3,2]形)

arr = [ [ [ nil, nil ],
          [ nil, nil ],
          [ nil, nil ] ],
        [ [ "*", nil ],
          [ nil, nil ],
          [ nil, nil ] ] ]

arr.flatten[6]           # => "*"
arr.index2coordinates(6) # => [1,0,0] or [1][0][0]

4D阵列([2,3,1,2]形)

arr = [ [ [ [ nil, nil ],
            [ nil, "*" ],
            [ nil, nil ] ] ],
        [ [ [ nil, nil ],
            [ nil, nil ],
            [ nil, nil ] ] ] ]

arr.flatten[3]           # => "*"
arr.index2coordinates(3) # => [0,0,1,1] or [0][0][1][1]

1D阵列([5]形)

arr = [ nil, nil, nil, "*", nil ]

arr.flatten[3]           # => "*"
arr.index2coordinates(3) # => [3]

我们如何做这样的Array#index2coordinates方法?从某种意义上说,这个问题与Convert vector to integer问题相反。非常感谢。

2 个答案:

答案 0 :(得分:3)

示例,一步一步:

# 3D array (of [2,3,2] shape)
arr.flatten[6]           # => "*"
arr.index2coordinates(6) # => [1,0,0] or [1][0][0]

6 % 2              # => 0

(6 / 2) % 3        # (3) % 3 => 0

((6 / 2) / 3) % 2  # ((3) / 3) %2 => 1 % 2 => 1


# 4D array (of [2,1,3,2] shape)    
arr.flatten[3]           # => "*"
arr.index2coordinates(3) # => [0,0,1,1] or [0][0][1][1]

3 % 2                     # => 1

(3 / 2) % 3               # => 1 % 3 => 1

((3 / 2) / 3) % 1         # => 1 % 1 => 0

(((3 / 2) / 3) / 1) % 2   # 0 % 2 => 0

第二个例子的简单代码

result = []
index = 3

[2,1,3,2].reverse.each do |dimension|
  result = [index % dimension] + result
  index = (index / dimension)
end

result          # => [0, 0, 1, 1]

答案 1 :(得分:0)

在输入每个步骤时,尝试通过构建n维索引的结构进行递归搜索,如果/当找到*目标时返回索引:

def coord(space, target='*', idx=[])
  found = nil
  space.each_with_index do |x,i|
    found = if x.is_a?(Array)
      coord(x, target, idx + [i])
    elsif x == target
      idx + [i]
    end
    break found if found
  end
  found
end

coord(arr3d) # => [1, 0, 0]
coord(arr4d) # => [0, 0, 1, 1]
coord(arr1d) # => [3]
coord([]) # => nil