logo

ジュリアのスプラットオペレータ 📂ジュリア

ジュリアのスプラットオペレータ

概要

Julia...はスプラット・オペレーターと呼ばれ、関数を使用したり、配列を定義する際に便利に使われる1。このオペレーターはJuliaに限定されているわけではないが、他の言語に比べて直感的に定義されており、学びやすく覚えやすいところが突出している。個人的な経験だと、...を使うようになるとJuliaプログラミングに関する何かしらの気づきを得る気がする。

コード

関数入力

基本的に...は配列やジェネレータの後に付けて使い、そのまま前にあるコンテナ/イテレータの要素を全部展開して出す。

julia> min([1,2,3,4,5,6,7,8,9,10])
ERROR: MethodError: no method matching min(::Vector{Int64})

julia> min(1,2,3,4,5,6,7,8,9,10)
1

例えばJuliaのmin()関数はリデュースとして働くから、そのまま配列を渡すのではなく、複数の数を直接引数として渡さなければならない。もちろん、配列が大きくなるほど手で全部解いて書くのは難しくなり、配列の要素を展開して入れることができるように...を使うことができる。

julia> min(1:10)
ERROR: MethodError: no method matching min(::UnitRange{Int64})

julia> min((1:10)...)
1

もちろん、実際は配列に使えるminimum()関数があるから、わざわざこうする必要はない。

配列定義

julia> [(1:10)]
1-element Vector{UnitRange{Int64}}:
 1:10

上で定義された配列はユニットレンジの配列なので、直接要素にアクセスするのが少し面倒になる。時間があれば、ただ単に1から10までの数字を書き込んだらいいけど、スプラットオペレータを使えば、次のように簡単に定義できる。

julia> [(1:10)...]
10-element Vector{Int64}:
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10

もちろん、collect()関数のような代替手段もあるが、知っておくときれいでセンスがある表現だという点が魅力的だ。ただし、速度の面ではあまり推奨されていないので、必要以上に...を使わないようにしよう。

julia> [eachrow(rand(3,3))...]
3-element Vector{SubArray{Float64, 1, Matrix{Float64}, Tuple{Int64, Base.Slice{Base.OneTo{Int64}}}, true}}:
 [0.6695368164913422, 0.69695509795356, 0.12084083239135612]
 [0.6833475867141307, 0.5368141950494666, 0.7877252857572066]
 [0.2810163716135018, 0.04317485597011517, 0.44214186775440534]

...が面白くなるのは、上のようにジェネレータを一度通るときだ。eachrow()は行列を行単位に切ったベクトルのジェネレータをリターンし、スプラットオペレータを通じて、その各ベクトルを配列表記[]に入れて、ベクトルのベクトルを作ったものだ。

全コード

min([1,2,3,4,5,6,7,8,9,10])
min(1,2,3,4,5,6,7,8,9,10)
min(1:10)
min((1:10)...)

[(1:10)]
[(1:10)...]
[eachrow(rand(3,3))...]

環境

  • OS: Windows
  • julia: v1.8.3