2016-06-18 9 views
5

Lassen Sie x::Vector{Vector{T}}. Was ist der beste Weg, um über alle Elemente eines jeden inneren Vektors zu iterieren (also alle Elemente vom Typ T)? Das Beste, was ich mit oben kommen kann ist eine doppelte Iteration der einzeilige Notation, das heißt:Was ist der einfachste Weg, um über ein Array von Arrays zu iterieren?

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

aber ich frage mich, ob es eine einzelne Iterator ist, vielleicht in dem Iterators Paket, speziell für diesen Zweck entworfen , z.B for i in some_iterator(x) ; x[i] ; end.

Allgemeiner gesagt, was ist mit der Iteration über die innersten Elemente eines Array-Arrays (dh Arrays jeder Dimension)?

+1

Verwenden des Iteratorpakets: 'für m in Kette (x ...) println (m); Ende. Sollte auch effizient sein. –

+0

@DanGetz Ah, das ist ordentlich! Danke vielmals. –

Antwort

7

Ihr Weg

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

ist ziemlich schnell. Wenn Sie beste Geschwindigkeit möchten, verwenden Sie

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

die zweimal vermeidet dereferencing (die erste dereferenzieren ist schwer zu optimieren, weil Arrays wandelbar sind, und so getindex ist nicht rein). Alternativ, wenn Sie nicht m und n brauchen, könnten Sie einfach

for y in x, for z in y 
    z 
end 

verwenden, die auch schnell.

Beachten Sie, dass Spalte-Hauptspeicher irrelevant ist, da alle Arrays hier eindimensional sind.

Ihre allgemeine Frage zu beantworten:

  • Wenn die Anzahl der Dimensionen eine Compile-Zeit konstant ist, siehe Base.Cartesian
  • Wenn die Anzahl der Dimensionen keine Compile-Zeit konstant ist, verwendet Rekursion

Und schließlich, als Dan Getz in einem Kommentar erwähnt:

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

funktioniert auch. Dies hat jedoch ein bisschen eine Leistungseinbuße.

+0

Wenn du sagst "Getindex" ist nicht rein - könntest du ein bisschen mehr erklären, was das bedeutet? Vielen Dank! –

+0

Danke für die Antwort - ich habe ein paar neue Dinge aus dieser Antwort gelernt. @DanGetz hatte auch in den Kommentaren zu der Frage, die Sie vielleicht in die Antwort aufnehmen möchten, einen ordentlichen Ansatz. Prost. –

+3

@aireties A [pure function] (https://en.wikipedia.org/wiki/Pure_function) ist eine Funktion, die immer dasselbe Ergebnis für die gleiche Eingabe zurückgibt und keine Nebenwirkungen hat. Zum Beispiel ist '+' auf Zahlen rein, weil '1 + 1' immer' 2' ist. Wenn ein Compiler erkennen kann, dass eine Funktion rein ist, kann sie es vermeiden, sie wiederholt zu berechnen. Leider ist 'getindex 'nicht rein, da' A [1] 'etwas anderes bedeuten könnte, wenn' A' mutiert wäre. Daher ist es für den Compiler sehr schwierig herauszufinden, dass 'x [n]' nicht jedes Mal berechnet werden muss. –