do syntaxについて
jupyter notebookのセルで以下を実行するとdoの説明が出てくる。
?do
Create an anonymous function and pass it as the first argument to a function call. For example:
map(1:10) do x
2x
end
is equivalent to map(x->2x, 1:10).
Use multiple arguments like so:
map(1:10, 11:20) do x, y
x + y
end
一番上の例だと、1から10という配列の各要素に対して、2倍をするという演算を行った配列を出力をする。普通のfor文との違いは、for文を回しただけだと、結果として配列は返ってこないが上記の例だと配列を返してくれる。
また、無名関数を使えば1行で書くことも可能である。
map(x->2x, 1:10)
例2: filter
奇数だけを出力する。
a = 1:10
filter(isodd, a)
をdoを使って書くと、
filter(1:10) do x
isodd(x)
end
偶数だけを取り出したい場合、
filter(1:10) do x
!isodd(x) # !はtrue or falseの否定を返す。
# iseven(x)でも良い
end
例3: findfirst
次のような配列list_param = [("a", -1), ("b", 2), ("a", 3)]
のうち、一番最初に"a"
が出てくる配列の要素が何番目なのか知りたい場合、
sampleidx = findfirst(list_param) do (k,v)
k == "a"
end
# 1
# list_param[sampleidx][2] == -1
# list_param[1] == list_param[sampleidx]
以下のように1行で書くことも可能?(しかし、以下のコードは間違っていますので正しい実装は、コメント欄を参照して下さい。)
target_key = "a"
sampleidx = findfirst((k,v) -> k == target_key, list_param)
例3:map&findfirstの組み合わせで配列の更新を行う
添字とそれに対応する値がセットになった配列があるとする。同じ添字を持つ複数の値を最初の値に揃えたい。
例えば、[("a", -1), ("b", 2), ("c", 3), ("a", 4),("b", 5)]
のような配列を ("a", -1),("b", 2), ("c", 3), ("a", -1) ,("b", 2)]
のように同じ添字を持つパラメタの値を同じにするような関数を作りたいとする。
function update(list_param, target_key)
sampleidx = findfirst(list_param) do (k, v)
k == target_key
end
map(list_param) do (k, v)
refk, refv = list_param[sampleidx] # target_keys とその値を返すのがpoint
if k == refk
(k, refv) # k=refk ならば、それに対応する値をタプルで返す。
else
(k, v) # そうでないなら、何もしない
end
end
end
# list_paramを更新させる。
list_param = [("a", -1), ("b", 2), ("a", 3)]
list_param = update(list_param, "a")
# kekka
# 3-element Vector{Tuple{String, Int64}}:
# ("a", -1)
# ("b", 2)
# ("a", -1)
より一般の場合に拡張するためfor文を使う。
list_param2 = [("a", -1), ("b", 2), ("c", 3), ("a", 4), ("b", 5)]
for target_key in ["a", "b", "c"]
list_param2 = update(list_param2, target_key)
println(list_param2)
end
これでlist_param2が所望のように更新される。
doについて理解を深めることができた。