2016-06-18 45 views
5

Lasciate x::Vector{Vector{T}}. Qual è il modo migliore per scorrere su tutti gli elementi di ciascun vettore interno (ovvero, tutti gli elementi di tipo T)? Il meglio che posso venire con è un doppio iterazione utilizzando la notazione a linea singola, cioè:Qual è il modo più semplice per scorrere su un array di array?

for n in eachindex(x), m in eachindex(x[n]) 
    x[n][m] 
end 

ma sto chiedendo se c'è un singolo iteratore, forse nel pacchetto Iterators, progettato specificamente per questo scopo , per esempio for i in some_iterator(x) ; x[i] ; end.

Più in generale, per quanto riguarda l'iterazione sugli elementi più interni di qualsiasi array di array (ovvero array di qualsiasi dimensione)?

+1

Utilizzo del pacchetto Iterators: 'per m in chain (x ...) println (m); FINE'. Dovrebbe essere efficiente pure. –

+0

@DanGetz Ah, è pulito! Grazie molto. –

risposta

7

Il tuo modo

for n in eachindex(x), m in eachindex(x[n]) 
    x[n][m] 
end 

è abbastanza veloce. Se si desidera che la migliore velocità, utilizzare

for n in eachindex(x) 
    y = x[n] 
    for m in eachindex(y) 
     y[m] 
    end 
end 

che evita dereferencing due volte (il primo dereference è difficile ottimizzare fuori perché gli array sono mutabili, e così getindex non è puro). In alternativa, se non hai bisogno di m e n, si potrebbe utilizzare

for y in x, for z in y 
    z 
end 

che è anche veloce.

Si noti che l'archiviazione su colonna principale è irrilevante, poiché tutti gli array qui sono unidimensionali.

Per rispondere alla tua domanda di carattere generale:

  • Se il numero di dimensioni è una fase di compilazione costante, vedere Base.Cartesian
  • Se il numero di dimensioni non è una costante in fase di compilazione, l'uso ricorsione

E, infine, come Dan Getz menzionato in un commento:

using Iterators 
for z in chain(x...) 
    z 
end 

funziona anche. Questo tuttavia ha un po 'di penalizzazione delle prestazioni.

+0

Quando dici 'getindex' non è puro - potresti fornire qualche spiegazione in più su cosa significhi? Grazie! –

+0

Grazie per aver risposto - Ho imparato alcune novità da questa risposta. @ DanGetz ha avuto un approccio pulito anche nei commenti sulla domanda che potresti voler incorporare nella risposta. Saluti. –

+3

@aireties Una [funzione pura] (https://en.wikipedia.org/wiki/Pure_function) è una funzione che restituisce sempre lo stesso risultato per lo stesso input e non ha effetti collaterali. Ad esempio, '+' sui numeri è puro, perché '1 + 1' sarà sempre' 2'. Se un compilatore può rilevare che una funzione è pura, può evitare di calcolarla ripetutamente. Sfortunatamente, 'getindex' non è puro, poiché' A [1] 'potrebbe significare qualcosa di diverso se" A "è stato mutato. Quindi è molto difficile per il compilatore capire che 'x [n]' non deve essere calcolato ogni volta. –