第9回Vimスクリプト入門みたいの(リスト追加・複製関数)

第7回から続いているリストの3回目。前回でリストから情報を取得できるようになったので、今度は要素を追加してみるよ。あとは、次回以降に備えて複製関数について。

" リストの追加用関数と複製用関数
" add(), insert(), extend(), +演算子, copy(), deepcopy()
"
" add(), insert(), extend(), +演算子
"
" add()

let a = range(1,5)
call add(a, 6)
echo a
echo add(a, range(7,10))

" リストに1つの要素を追加し、追加後のリストを返す。
" 注意すべき点は2つ。
" 1つめは、第1引数自体に変更を加えに行くこと。
" 2つめは、リストを第2引数に与えても展開されて追加されず、
" リストとして追加される(リストの入れ子になる)こと。
" 展開して追加(結合)したいときは extend() を使用する。
"
" insert()

let a = range(6,10)
echo insert(a, range(1,5), 0)

" リストに1つの要素を挿入し、挿入後のリストを返す。
" 第3引数で挿入位置が指定できる点を除いてadd()とほぼ同じ動作をする。
" 注意点もadd()と同じ。( なのでサンプルも簡単にしてみた )
"
" extend()

let a = range(1,5)
call extend(a, range(8,10))
echo a
echo extend(a, range(6,7), 5)

" リストを連結し、連結後のリストを返す。
" add(),insert()と同様に第1引数に変更をかけにいく。
" add(),insert()とは違い、リストが展開されて挿入され、
" リスト以外は挿入ができない。
" 第3引数なしで使うと+演算子の動作と多分同じ。
" (余談)expand()とは名前は似ているが別物。
"
" +演算子

echo range(1,5) + range(6,7) + range(8,10)

" せっかく話がでてきたので出しとくね。
" ただ追加するなら、簡単だし、こっち使うといいよ。
"
" ここからは複製用の関数。
" 今までの追加・挿入・連結の関数は引数自体を操作していたが、
" これらに変更を加えたくない場合には、複製が必要になる。
" そういう感じの話の流れで。
"
" copy(), deepcopy()
"
" copy()

let a1 = [1, 2, ['a', 'b']]
let a2 = copy(a1)
call add(a1, 3)
echo a2
call add(a1[2], 'c')
echo a1
echo a2

" リストの複製を返す。参照のコピーではないが浅いコピーなので
" リストの中にあるリスト等を変更するとコピー先も変更されてしまう。
" 完全なコピーが欲しいなら deepcopy() を使う。速度などに問題がなければ、
" deepcopy()を使うことを推奨。まぎらわしいしね。
"
" deepcopy()

let a1 = [1, 2, ['a', 'b']]
let a2 = deepcopy(a1)
call add(a1, 3)
echo a2
call add(a1[2], 'c')
echo a1
echo a2

" リストの複製を返す。サンプルはcopy()のものとほぼ同じ。
" こちらは完全なコピーなので、a1の変更は一切a2には影響しない。
"
" 今回のまとめ
" add()
" insert()
" extend()
" +演算子
" copy()
" deepcopy()
"