2009-12-05 26 views
8

Provato risorse web e non ho avuto fortuna e la mia guida visiva di avvio rapido.Come trovo .index di un array multidimensionale

Se ho la mia 2d/array multidimensionale:

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

    print array.index('S') 

    it returns nil 

Allora ho andare e tipo:

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

restituisce il valore Cerco 1

La mia prima risposta qualcosa viene chiamato errato in .index() e ha bisogno di due argomenti uno per riga e colonna? In ogni caso, come faccio a .index lavorare per un array multidimensionale? Questo è il primo passo per risolvere il mio piccolo problema di labirinto

+0

Una cosa che non ho visto menzionato nei vari (molto buono) le risposte che Ruby era in realtà non supporta gli array 2D - sono davvero array di array , quindi la ricerca a due livelli. –

risposta

4
a.each_index { |i| j = a[i].index 'S'; p [i, j] if j } 

Aggiornamento: OK, possiamo ret urna più partite. Probabilmente è meglio utilizzare il core API il più possibile, piuttosto che iterare uno a uno con il codice Ruby interpretato, quindi aggiungiamo alcune uscite di cortocircuito e evalation iterative per spezzare la riga in pezzi. Questa volta è organizzato come metodo di istanza su Array e restituisce una matrice di sottoreti [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' 
+0

probabilmente chiedendo molto come gestirei più valori nell'array? come la 'x' quando l'ho eseguito è tornato con i valori per la prima colonna non per tutte le colonne. Ho provato alcune cose e ancora senza fortuna. Suggerimenti? – Matt

+0

Certo, posso pubblicare un aggiornamento in un minuto. (Mi chiedo perché ha ottenuto un down-down drive-by?Non è un grosso problema, solo curioso ...) – DigitalRoss

0

Risposta specifica non ruby: stai provando a stampare "S" in entrambi gli esempi, ma solo quest'ultimo ha "S" nell'array. Il primo ha ['x', 'S', '', 'x']. Quello che devi fare (se Ruby non fa questo per te) è guardare ogni membro dell'array e cercare quel membro per "S". Se "S" è contenuto in quel membro, quindi stamparlo.

4

Si potrebbe trovare prima in cui è la posizione assoluta appiattendo la matrice:

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

quindi ottenere il numero di colonne per riga:

ncols = array.first.size 

poi

row = pos/ncols 

col = pos % ncols 
+0

È possibile sostituire le ultime due righe con 'row, col = pos.divmod (ncols)'. –

12

Questo lo farà:

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

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

Se si desidera anche 'indice di S nella matrice sub si potrebbe:

row = array.detect{|aa| aa.include?('S')} 
p [row.index('S'), array.index(row)] # prints [1,1] 
+0

Sta stampando la riga (cioè l'array nidificato) in cui si trova, non la sua posizione nel sottoarray. Non è del tutto chiaro dalla domanda su quale indice sia (anche se la seconda risposta stampa entrambi). – samg

+0

alla fine volevo ottenere entrambi gli indici in modo da poter includere in una statistica if più avanti – Matt

+0

Molto utile! Grazie per questo! – shedd

0
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

Specifica entrambi gli indici della prima occorrenza di elemento per una passata su subarray

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 
3

È possibile utilizzare il metodo Matrix#index:

require 'matrix' 

Matrix[*array].index("S") 
    #=> [1, 1] 
+0

Questa dovrebbe essere la risposta accettata. Offusca molta complessità ma è elegante e semplice. – ACIDSTEALTH

+0

Grazie @Cary Swoveland Questo mi ha davvero aiutato in un complesso problema di foglio elettronico che stavo cercando di risolvere. Non ho mai saputo che Ruby aveva una classe Matrix –

Problemi correlati