下のfor-in
文で書いているような多次元配列から要素を見つける方法をlazy.filter
のようにかけないでしょうか?
配列をflatにする方法なら思いつくのですが、その場合はlazy.filter
のメリットが消えてしまうと思いまして。
swift
1 2let mdArray = [[[1, 2], [3, 4]], [[5, 6], [7, 8]], [[9, 10], [11, 12]]] 3 4func find(_ int: Int) -> Int? { 5 6 var count = 0 7 8 for i in mdArray { 9 10 for j in i { 11 12 for k in j { 13 14 count += 1 15 print(count) 16 17 if k == int { 18 return k 19 } 20 21 } 22 } 23 } 24 return nil 25} 26 27let i = find(5) 28
swift
1let array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] 2 3let r = array.lazy.filter { $0 == 5 } .first 4 5print(r) // (6 times)
> lazy.filterのメリット
は何を指しているでしょうか? (実行速度?メモリ効率?
質問例では
- filter を1チェーンしかしていないので lazyの意味がない
- lazy.filter{}.first だとリストの要素すべてを走査 + 1つだけ残った配列分メモリ確保される
のでそもそも for での実装例よりパフォーマンスが悪いと思います。
また、1つ見つけるという操作は lazy にできないので、質問の意図がわかっていないですmm
playgroundで確認したろころ
array.lazy.filter { $0 == 5 }.first // => 6times
array.filter { $0 == 5 } .first // => 11times
となっていましたので、
timesがなにを表しているか調べませんでしたが、当然全要素にアクセスしていないと解釈してました。
この場合のlazyはリスト要素すべてを走査 + 1つだけ残った配列分メモリを確保するのですね。
知りませんでした、ありがとうございます。
メリットはforとの比較でのメリットではなく、
配列をフラットにした後に、lazy.filterするとコスト的なメリットがなくなると考えたのですが、
unhappychoiceが教えてくださったような動作をするようでしたら、もともとlazyをつけることにメリットはないということですね。
> この場合のlazyはリスト要素すべてを走査 + 1つだけ残った配列分メモリを確保するのですね。
あ、これは for文 で書いたときに比べ、filterの返り値に余分に新しい配列を作るので、の対比でした
lazy は map / filter を複数チェーンしたときに、都度配列を作らなくするため、メモリと実行速度が向上するというものです。
(ので、複数チェーンしない限りは基本的に意味はない
playgroundのtimesってなんですかね。arrayとfilterとfirstしか書いてないんですが。
LazyFilterSequenceは元のSequenceとfilterの関数だけを持ったstructで生成時点では新たな配列は生成していません
firstなどのcomputedなプロパティやメソッドが呼ばれた時に初めて要素に対して関数等が適用されます
この時戻り値としての値が生成された段階でSequenceの走査を打ち切りますのでその分効率が良いということです
lazy.filter{ ... }.firstであれば
たとえば1万の要素があったとしても1番目の要素がfilter関数にtrueを返せばfilter関数は1度しか実行されません。もちろんSequenceの走査も1要素のみです
MasakiHoriさんの説明で、今まで自分が学習したことがそれほど間違っていないことを確認できて安心しました。
回答1件
あなたの回答
tips
プレビュー