LoginSignup
9
3

More than 5 years have passed since last update.

Julia でも array.map() do ... end と書ける

Last updated at Posted at 2016-12-27

 Julia Advent Calendar 2016 です。12月9日の記事を 12月27日に投稿しました。

 Julia でも、Ruby のようなオブジェクト指向の構文で書きたい。その要望に Lazy.jl パッケージが応えます。

(その1) 文字列置換

 文字列を置換するには replace を使います。

julia> s="123"
"123"

julia> s=replace(s,"2","b")
"1b3"

julia> s=replace(s,"3","c")
"1bc"

 replace は、元の文字列を更新しません (文字列は immutable だから)。ですので、文字列置換を複数回行うには、s=replace(s,from,to) を繰り返して適用することになります。面倒ですね。
 Ruby では、これをメソッド・チェーンできれいに書けます。一時変数も不要です。

 Ruby
"123".sub("2","b") # => "1b3"
"123".sub("2","b").sub("3","c") # => "1bc"

 Julia では、 Base.|> を使って function chain を書けますが、無名関数を書く必要があり、いまいちイケていません。(別記事へのコメント )


julia> "123" |> (x -> replace(x,"2","b")) |> (x -> replace(x,"3","c"))
"1bc"

 さて、クリスマス・プレゼントに、Lazy.jl パッケージを頂きました。
 @> マクロを使えば、Julia でも似たように書けますよ。

julia> Pkg.add("Lazy")

julia> using Lazy

julia> @> "123" replace("2","b")
"1b3"

julia> @> "123" replace("2","b") replace("3","c")
"1bc"

 繰り返し文字列置換を適用できて、大満足です。

(その2) map, foreach

 Julia の mapmap(func, collection...) という引数をとります。func を do...end ブロックで後置する構文もあります。いずれにせよ map から始まります。

julia> map(x-> sin(x), [1,2,3])
3-element Array{Float64,1}:
 0.841471
 0.909297
 0.14112

julia> map([1,2,3]) do x sin(x) end
3-element Array{Float64,1}:
 0.841471
 0.909297
 0.14112

 Ruby のmap は、配列に対する操作を簡潔に書けますね。

# Ruby
[1,2,3].map do |x| Math.sin(x); end
# => [0.8414709848078965, 0.9092974268256817, 0.1411200080598672]

 Ruby がうらやましい ?
 いやいや、@>> マクロを使えば、Julia でも似たように書けますよ。

julia> @>> [1,2,3] map() do x sin(x) end
3-element Array{Float64,1}:
 0.841471
 0.909297
 0.14112

 計算結果が不要なら foreach を使いましょう。

julia> @>> [1,2,3] foreach() do x println(sin(x)) end
0.8414709848078965
0.9092974268256817
0.1411200080598672

種明かしは初夢で

 Lazy.jl のドキュメントをどうぞ。
 https://github.com/MikeInnes/Lazy.jl#macros

(その3) map を連結できる

2017/01/03 追記

( 初夢を見ました。まだ種明かしはしませんが )

# Ruby
[1,2,3].collect{|x| Math.sin(x)}.collect{|x| x+1 }
# => [1.8414709848078965, 1.9092974268256817, 1.1411200080598671]

Julia でも map を連結できます。

julia> @>> [1,2,3] map() do x sin(x) end map() do x x+1 end
3-element Array{Float64,1}:
 1.84147
 1.9093 
 1.14112
9
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
3