Iteration utilities

Base.Iterators.StatefulType
Stateful(itr)

このイテレータラッパーについて考える方法はいくつかあります:

  1. イテレータとそのイテレーション状態を包む可変ラッパーを提供します。
  2. イテレータのような抽象を Channel のような抽象に変換します。
  3. アイテムが生成されるたびに、自身の残りのイテレータになるように変化するイテレータです。

Stateful は通常のイテレータインターフェースを提供します。他の可変イテレータ(例: Base.Channel)と同様に、イテレーションが早期に停止した場合(例: for ループ内の break によって)、同じイテレータオブジェクトを使ってイテレーションを再開することができます(対照的に、不変イテレータは最初から再スタートします)。

julia> a = Iterators.Stateful("abcdef");

julia> isempty(a)
false

julia> popfirst!(a)
'a': ASCII/Unicode U+0061 (category Ll: Letter, lowercase)

julia> collect(Iterators.take(a, 3))
3-element Vector{Char}:
 'b': ASCII/Unicode U+0062 (category Ll: Letter, lowercase)
 'c': ASCII/Unicode U+0063 (category Ll: Letter, lowercase)
 'd': ASCII/Unicode U+0064 (category Ll: Letter, lowercase)

julia> collect(a)
2-element Vector{Char}:
 'e': ASCII/Unicode U+0065 (category Ll: Letter, lowercase)
 'f': ASCII/Unicode U+0066 (category Ll: Letter, lowercase)

julia> Iterators.reset!(a); popfirst!(a)
'a': ASCII/Unicode U+0061 (category Ll: Letter, lowercase)

julia> Iterators.reset!(a, "hello"); popfirst!(a)
'h': ASCII/Unicode U+0068 (category Ll: Letter, lowercase)
julia> a = Iterators.Stateful([1,1,1,2,3,4]);

julia> for x in a; x == 1 || break; end

julia> peek(a)
3

julia> sum(a) # 残りの要素の合計
7
source
Base.Iterators.zipFunction
zip(iters...)

複数のイテレータを同時に実行し、そのうちのいずれかが尽きるまで続けます。zipイテレータの値の型は、そのサブイテレータの値のタプルです。

Note

zipは、状態を持つイテレータが現在のイテレーションで他のイテレータが終了したときに進まないように、サブイテレータへの呼び出しを順序付けます。

Note

引数なしのzip()は、空のタプルの無限イテレータを生成します。

参照: enumerate, Base.splat.

julia> a = 1:5
1:5

julia> b = ["e","d","b","c","a"]
5-element Vector{String}:
 "e"
 "d"
 "b"
 "c"
 "a"

julia> c = zip(a,b)
zip(1:5, ["e", "d", "b", "c", "a"])

julia> length(c)
5

julia> first(c)
(1, "e")
source
Base.Iterators.enumerateFunction
enumerate(iter)

1から始まるカウンタiと、与えられたイテレータからのi番目の値xを返すイテレータです。イテレートしている値xだけでなく、これまでのイテレーションの回数も必要な場合に便利です。

iiterのインデックスとして有効でない場合や、異なる要素をインデックスする場合があります。これは、iterのインデックスが1から始まらない場合に発生し、文字列や辞書などで起こる可能性があります。iがインデックスであることを保証したい場合は、pairs(IndexLinear(), iter)メソッドを参照してください。

julia> a = ["a", "b", "c"];

julia> for (index, value) in enumerate(a)
           println("$index $value")
       end
1 a
2 b
3 c

julia> str = "naïve";

julia> for (i, val) in enumerate(str)
           print("i = ", i, ", val = ", val, ", ")
           try @show(str[i]) catch e println(e) end
       end
i = 1, val = n, str[i] = 'n'
i = 2, val = a, str[i] = 'a'
i = 3, val = ï, str[i] = 'ï'
i = 4, val = v, StringIndexError("naïve", 4)
i = 5, val = e, str[i] = 'v'
source
Base.Iterators.countfromFunction
countfrom(start=1, step=1)

永遠にカウントするイテレータで、startから始まり、stepずつ増加します。

julia> for v in Iterators.countfrom(5, 2)
           v > 10 && break
           println(v)
       end
5
7
9
source
Base.Iterators.takeFunction
take(iter, n)

イテレータで、iterの最初のn要素を最大で生成します。

関連項目: drop, peel, first, Base.take!.

julia> a = 1:2:11
1:2:11

julia> collect(a)
6-element Vector{Int64}:
  1
  3
  5
  7
  9
 11

julia> collect(Iterators.take(a,3))
3-element Vector{Int64}:
 1
 3
 5
source
Base.Iterators.takewhileFunction
takewhile(pred, iter)

iterから、述語predが真である限り要素を生成するイテレータであり、その後はすべての要素をドロップします。

Julia 1.4

この関数は少なくともJulia 1.4が必要です。

julia> s = collect(1:5)
5-element Vector{Int64}:
 1
 2
 3
 4
 5

julia> collect(Iterators.takewhile(<(3),s))
2-element Vector{Int64}:
 1
 2
source
Base.Iterators.dropFunction
drop(iter, n)

最初の n 要素を除いた iter のすべての要素を生成するイテレータ。

julia> a = 1:2:11
1:2:11

julia> collect(a)
6-element Vector{Int64}:
  1
  3
  5
  7
  9
 11

julia> collect(Iterators.drop(a,4))
2-element Vector{Int64}:
  9
 11
source
Base.Iterators.dropwhileFunction
dropwhile(pred, iter)

iterから要素を削除するイテレータで、述語predが真である限り要素を削除し、その後はすべての要素を返します。

Julia 1.4

この関数は少なくともJulia 1.4が必要です。

julia> s = collect(1:5)
5-element Vector{Int64}:
 1
 2
 3
 4
 5

julia> collect(Iterators.dropwhile(<(3),s))
3-element Vector{Int64}:
 3
 4
 5
source
Base.Iterators.cycleFunction
cycle(iter[, n::Int])

iterを永遠に循環するイテレータです。nが指定されている場合、iterをその回数だけ循環します。iterが空の場合、cycle(iter)およびcycle(iter, n)も空になります。

Iterators.cycle(iter, n)Base.repeat(vector, n)の遅延版に相当し、Iterators.repeated(iter, n)は遅延Base.fill(item, n)です。

Julia 1.11

メソッドcycle(iter, n)はJulia 1.11で追加されました。

julia> for (i, v) in enumerate(Iterators.cycle("hello"))
           print(v)
           i > 10 && break
       end
hellohelloh

julia> foreach(print, Iterators.cycle(['j', 'u', 'l', 'i', 'a'], 3))
juliajuliajulia

julia> repeat([1,2,3], 4) == collect(Iterators.cycle([1,2,3], 4))
true

julia> fill([1,2,3], 4) == collect(Iterators.repeated([1,2,3], 4))
true
source
Base.Iterators.repeatedFunction
repeated(x[, n::Int])

x を永遠に生成するイテレータです。n が指定されている場合、x をその回数だけ生成します(take(repeated(x), n) と同等です)。

他に fill を参照し、Iterators.cycle と比較してください。

julia> a = Iterators.repeated([1 2], 4);

julia> collect(a)
4-element Vector{Matrix{Int64}}:
 [1 2]
 [1 2]
 [1 2]
 [1 2]

julia> ans == fill([1 2], 4)
true

julia> Iterators.cycle([1 2], 4) |> collect |> println
[1, 2, 1, 2, 1, 2, 1, 2]
source
Base.Iterators.productFunction
product(iters...)

複数のイテレータの積に対するイテレータを返します。生成される各要素はタプルで、その i 番目の要素は i 番目の引数イテレータから来ます。最初のイテレータが最も速く変化します。

参照: zip, Iterators.flatten.

julia> collect(Iterators.product(1:2, 3:5))
2×3 Matrix{Tuple{Int64, Int64}}:
 (1, 3)  (1, 4)  (1, 5)
 (2, 3)  (2, 4)  (2, 5)

julia> ans == [(x,y) for x in 1:2, y in 3:5]  # Iterators.productを含むジェネレータを収集
true
source
Base.Iterators.flattenFunction
flatten(iter)

イテレータを受け取り、そのイテレータが生成するイテレータの要素を返すイテレータを返します。言い換えれば、引数のイテレータの要素が連結されます。

julia> collect(Iterators.flatten((1:2, 8:9)))
4-element Vector{Int64}:
 1
 2
 8
 9

julia> [(x,y) for x in 0:1 for y in 'a':'c']  # Iterators.flattenを含むジェネレータを収集
6-element Vector{Tuple{Int64, Char}}:
 (0, 'a')
 (0, 'b')
 (0, 'c')
 (1, 'a')
 (1, 'b')
 (1, 'c')
source
Base.Iterators.flatmapFunction
Iterators.flatmap(f, iterators...)

flatten(map(f, iterators...)) と同等です。

Iterators.flattenIterators.map も参照してください。

Julia 1.9

この関数は Julia 1.9 で追加されました。

julia> Iterators.flatmap(n -> -n:2:n, 1:3) |> collect
9-element Vector{Int64}:
 -1
  1
 -2
  0
  2
 -3
 -1
  1
  3

julia> stack(n -> -n:2:n, 1:3)
ERROR: DimensionMismatch: stack expects uniform slices, got axes(x) == (1:3,) while first had (1:2,)
[...]

julia> Iterators.flatmap(n -> (-n, 10n), 1:2) |> collect
4-element Vector{Int64}:
 -1
 10
 -2
 20

julia> ans == vec(stack(n -> (-n, 10n), 1:2))
true
source
Base.Iterators.partitionFunction
partition(collection, n)

コレクションを n 要素ずつ反復処理します。

julia> collect(Iterators.partition([1,2,3,4,5], 2))
3-element Vector{SubArray{Int64, 1, Vector{Int64}, Tuple{UnitRange{Int64}}, true}}:
 [1, 2]
 [3, 4]
 [5]
source
Base.Iterators.mapFunction
Iterators.map(f, iterators...)

遅延マッピングを作成します。これは、(f(args...) for args in zip(iterators...))を書くための別の構文です。

Julia 1.6

この関数は少なくともJulia 1.6を必要とします。

julia> collect(Iterators.map(x -> x^2, 1:3))
3-element Vector{Int64}:
 1
 4
 9
source
Base.Iterators.filterFunction
Iterators.filter(flt, itr)

与えられた述語関数 flt と反復可能なオブジェクト itr に対して、flt(x) を満たす itr の要素 x を反復する際に返す反復可能なオブジェクトを返します。元のイテレータの順序は保持されます。

この関数は 遅延 です。すなわち、$Θ(1)$ 時間で返すことが保証され、$Θ(1)$ の追加スペースを使用し、filter の呼び出しによって flt は呼び出されません。返された反復可能なオブジェクトを反復する際に flt への呼び出しが行われます。これらの呼び出しはキャッシュされず、再反復時には再度呼び出されます。

Warning

filter から返されたイテレータに対するその後の 遅延 変換、例えば Iterators.reversecycle によって行われるものは、返された反復可能なオブジェクトを収集または反復するまで flt への呼び出しを遅延させます。フィルタ述語が非決定的であるか、その戻り値が itr の要素に対する反復の順序に依存する場合、遅延変換との合成は驚くべき動作を引き起こす可能性があります。これが望ましくない場合は、flt が純粋な関数であることを確認するか、中間の filter イテレータを収集してからさらなる変換を行ってください。

配列のフィルタリングのためのイagerな実装については Base.filter を参照してください。

julia> f = Iterators.filter(isodd, [1, 2, 3, 4, 5])
Base.Iterators.Filter{typeof(isodd), Vector{Int64}}(isodd, [1, 2, 3, 4, 5])

julia> foreach(println, f)
1
3
5

julia> [x for x in [1, 2, 3, 4, 5] if isodd(x)]  # Iterators.filter 上のジェネレータを収集
3-element Vector{Int64}:
 1
 3
 5
source
Base.Iterators.accumulateFunction
Iterators.accumulate(f, itr; [init])

2つの引数を持つ関数 f とイテレータ itr を与えると、前の値と itr の次の要素に f を順次適用する新しいイテレータを返します。

これは実質的に Base.accumulate の遅延バージョンです。

Julia 1.5

キーワード引数 init は Julia 1.5 で追加されました。

julia> a = Iterators.accumulate(+, [1,2,3,4]);

julia> foreach(println, a)
1
3
6
10

julia> b = Iterators.accumulate(/, (2, 5, 2, 5); init = 100);

julia> collect(b)
4-element Vector{Float64}:
 50.0
 10.0
  5.0
  1.0
source
Base.Iterators.reverseFunction
Iterators.reverse(itr)

イテレータ itr が与えられた場合、reverse(itr) は同じコレクションの逆順のイテレータです。このイテレータは「遅延」であり、逆順にするためにコレクションのコピーを作成しません; 詳細は Base.reverse を参照してください。

(デフォルトでは、これは itr をラップする Iterators.Reverse オブジェクトを返します。これは、対応する iterate メソッドが定義されている場合にイテレート可能ですが、一部の itr タイプはより専門的な Iterators.reverse の動作を実装している場合があります。)

すべてのイテレータタイプ T が逆順のイテレーションをサポートしているわけではありません。 T がサポートしていない場合、Iterators.reverse(itr::T) をイテレートすると、Iterators.Reverse{T}iterate メソッドが欠けているため、MethodError がスローされます。(これらのメソッドを実装するには、元のイテレータ itr::Tr::Iterators.Reverse{T} オブジェクトから r.itr によって取得できます; より一般的には、Iterators.reverse(r) を使用できます。)

julia> foreach(println, Iterators.reverse(1:5))
5
4
3
2
1
source
Base.Iterators.onlyFunction
only(x)

コレクション x の唯一の要素を返すか、コレクションに要素がゼロまたは複数ある場合は ArgumentError をスローします。

関連情報として firstlast も参照してください。

Julia 1.4

このメソッドは少なくとも Julia 1.4 を必要とします。

julia> only(["a"])
"a"

julia> only("a")
'a': ASCII/Unicode U+0061 (category Ll: Letter, lowercase)

julia> only(())
ERROR: ArgumentError: Tuple contains 0 elements, must contain exactly 1 element
Stacktrace:
[...]

julia> only(('a', 'b'))
ERROR: ArgumentError: Tuple contains 2 elements, must contain exactly 1 element
Stacktrace:
[...]
source
Base.Iterators.peelFunction
peel(iter)

最初の要素と残りの要素に対するイテレータを返します。

イテレータが空の場合は nothing を返します(iterate のように)。

Julia 1.7

以前のバージョンでは、イテレータが空の場合に BoundsError が発生します。

参照: Iterators.drop, Iterators.take.

julia> (a, rest) = Iterators.peel("abc");

julia> a
'a': ASCII/Unicode U+0061 (category Ll: Letter, lowercase)

julia> collect(rest)
2-element Vector{Char}:
 'b': ASCII/Unicode U+0062 (category Ll: Letter, lowercase)
 'c': ASCII/Unicode U+0063 (category Ll: Letter, lowercase)
source