tags:

views:

275

answers:

6

Tried web resources and didnt have any luck and my visual quick start guide.

If I have my 2d/multidimensional array:

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

   print array.index('S')

   it returns nil

So then I go and type:

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

it returns the value I am looking for 1

My first guess something is being called wrong in the .index() and it needs two arguments one for both row and column? Anyways how do I make .index work for a multidimensional array? This is step one for solving my little maze problem

A: 

Non-Ruby specific answer: You're trying to print 'S' in both examples, but only the latter has 'S' in the array. The first has ['x', 'S', ' ', 'x']. What you will need to do (If Ruby doesn't do this for you) is look at each member in the array and search that member for 'S'. If 'S' is contained in that member then print it.

Peter C.
A: 

You could find first in which is the absolute position by flattening the array:

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

Then get the number of columns per row:

ncols = array.first.size

then

row = pos / ncols

col = pos % ncols
duncan
+1  A: 
a.each_index { |i| j = a[i].index 'S'; p [i, j] if j }

Update: OK, we can return multiple matches. It's probably best to utilize the core API as much as possible, rather than iterate one by one with interpreted Ruby code, so let's add some short-circuit exits and iterative evals to break the row into pieces. This time it's organized as an instance method on Array, and it returns an array of [row,col] subarrays.

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'
DigitalRoss
probably asking alot how would I handle multiple values in the array? such as the 'x' when I ran it it came back with the values for the first column not all columns. Tried a few things out and still no luck. Suggestions?
Matt
Sure, I can post an update in a minute. (I wonder why it got a drive-by downvote? No big deal, just curious...)
DigitalRoss
+4  A: 

This will do it:

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

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

If you also want 'S's index in the sub array you could:

row = array.detect{|aa| aa.include?('S')}
p [row.index('S'), array.index(row)] # prints [1,1]
samg
It's printing which row (i.e. nested array) it's in, not it's location in the subarray. It's not totally clear from the question which index he's after (although the second answer prints both).
samg
ultimatly wanted to get both indicies so I can include in a if statment later
Matt
Very helpful! Thanks for this!
shedd
A: 
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
Hooopo
A: 

Specifies both indexes of the first occurrence of element for one pass on subarrays

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
aaz