2016-06-18 24 views
5

x::Vector{Vector{T}}とする。各内部ベクトルのすべての要素(つまり、タイプTのすべての要素)を反復処理する最良の方法は何ですか?私が思い付くことができる最高のは、シングルラインの表記法を用いた二重反復、すなわちです:配列の配列を反復処理する最も簡単な方法は何ですか?

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

おそらくIteratorsパッケージで、この目的のために特別に設計された、単一のイテレータがある場合、私は思ったんだけど、例えばfor i in some_iterator(x) ; x[i] ; end

さらに一般的には、どの配列の配列(つまり、任意の次元の配列)の最も内側の要素を反復処理するのですか?

+1

イテレータパッケージを使用する: 'for m in chain(x ...)println(m);終わり。効率的でなければならない。 –

+0

@DanGetzああ、それはすてきです!どうもありがとう。 –

答えて

7

あなたの道

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

はかなり速いです。あなたは最高のスピードをしたい場合は、二回逆参照することを回避する

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

を使用します(最初のデリファレンスは配列が可変であるため、アウト最適化することは困難である、とそうgetindexは純粋ではありません)。あなたはmnを必要としない場合は別の方法として、あなただけのも速いです

for y in x, for z in y 
    z 
end 

を使用することができます。

ここで、すべての配列は1次元なので、列の主要な記憶域は無関係であることに注意してください。次元の数は、コンパイル時定数である場合には、

  • 次元の数は、使用再帰
  • コンパイル時の定数ではない場合 Base.Cartesian
  • を参照してください。

    はあなたの一般的な質問に答えるために

    using Iterators 
    for z in chain(x...) 
        z 
    end 
    
    :ダン・ゲッツコメントで述べたように

そして最後に、

も動作します。しかしこれには少しのパフォーマンス上のペナルティがあります。

+0

'getindex'が純粋ではないと言うと、それは何を意味するのか、もう少し説明できますか?ありがとう! –

+0

応答ありがとう - 私はこの答えからいくつかの新しいことを学びました。 @ダンゲッツ氏は、あなたが答えに取り入れたいかもしれない質問に関するコメントにも、きちんとしたアプローチをしていました。乾杯。 –

+3

@aireties [pure関数](https://en.wikipedia.org/wiki/Pure_function)は、同じ入力に対して常に同じ結果を返し、副作用がない関数です。例えば、 '1 + 1'は常に' 2'であるため、数字の '+'は純粋です。コンパイラが関数が純粋であることを検出できれば、それを繰り返し計算することを避けることができます。 'A 'が突然変異した場合、' A [1] 'は何か異なることを意味するかもしれないので、' getindex'は純粋ではありません。だから、コンパイラが毎回 'x [n] 'を計算する必要がないことを理解することは非常に難しいです。 –

関連する問題