Как мне найти .index многомерного массива - PullRequest
8 голосов
/ 05 декабря 2009

Попробовал веб-ресурсы и не повезло, и мое краткое руководство.

Если у меня есть двумерный / многомерный массив:

 array = [['x', 'x',' x','x'],
         ['x', 'S',' ','x'],
         ['x', 'x',' x','x']]

   print array.index('S')

   it returns nil

Итак, я иду и набираю:

 array = ['x', 'S',' ','x']
 print array.index('S')

возвращает значение, которое я ищу 1

Мое первое предположение: что-то не так вызывается в .index (), и ему нужны два аргумента, один для строки и столбца? В любом случае, как заставить работать .index для многомерного массива? Это первый шаг к решению моей маленькой проблемы с лабиринтом

Ответы [ 7 ]

12 голосов
/ 05 декабря 2009

Это сделает это:

array = [['x', 'x',' x','x'],
         ['x', 'S',' ','x'],
         ['x', 'x',' x','x']]

p array.index(array.detect{|aa| aa.include?('S')}) # prints 1

Если вам также нужен индекс 'S в подмассиве, вы можете:

row = array.detect{|aa| aa.include?('S')}
p [row.index('S'), array.index(row)] # prints [1,1]
5 голосов
/ 30 января 2015

Вы можете использовать метод Matrix # index :

require 'matrix'

Matrix[*array].index("S")
  #=> [1, 1]
4 голосов
/ 05 декабря 2009
a.each_index { |i| j = a[i].index 'S'; p [i, j] if j }

Обновление: ОК, мы можем вернуть несколько совпадений. Вероятно, лучше использовать как можно больше базового API, а не повторять один за другим с интерпретированным кодом Ruby, поэтому давайте добавим несколько выходов короткого замыкания и итеративных ошибок, чтобы разбить строку на части. На этот раз он организован как метод экземпляра в Array и возвращает массив [row, col] подмассивов.

a = [ %w{ a b c d },
      %w{ S },
      %w{ S S S x y z },
      %w{ S S S S S S },
      %w{ x y z S },
      %w{ x y S a b },
      %w{ x },
      %w{ } ]

class Array
  def locate2d test
    r = []
    each_index do |i|
      row, j0 = self[i], 0
      while row.include? test
        if j = (row.index test)
          r << [i, j0 + j]
          j  += 1
          j0 += j
          row = row.drop j
        end
      end
    end
    r
  end
end

p a.locate2d 'S'
4 голосов
/ 05 декабря 2009

Сначала вы можете найти абсолютную позицию, сгладив массив:

pos = array.flatten.index('S')

Затем получите количество столбцов в строке:

ncols = array.first.size

тогда

row = pos / ncols

col = pos % ncols
0 голосов
/ 05 декабря 2009

Указывает оба индекса первого появления элемента для одного прохода по подмассивам

a = [[...],[...],[...],[...]]
element = 'S'
result_i = result_j = nil

a.each_with_index do|row, i|
    if (j = row.index(element))
        result_i, result_j = i, j       
        break
    end
end
0 голосов
/ 05 декабря 2009
array = [['x', 'x',' x','x'],
         ['x', 'S',' ','x'],
         ['x', 'x',' x','x']]
class Array
  def my_index item
    self.each_with_index{|raw, i| return i if raw.include? item}
    return
  end
end

p array.my_index("S") #=>1
p array.my_index("Not Exist Item") #=> nil
0 голосов
/ 05 декабря 2009

Ответ, не относящийся к Ruby: вы пытаетесь напечатать 'S' в обоих примерах, но только в последнем есть 'S' в массиве. Первый имеет ['x', 'S', '', 'x']. То, что вам нужно будет сделать (если Ruby не сделает этого за вас), это посмотреть на каждого члена в массиве и найти для этого члена 'S'. Если в этом элементе содержится буква «S», выведите его.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...