VimScript のリスト操作
VimScript には、リスト操作を行う組み込み関数が用意されているんですが、複数の操作を行う場合、関数の呼び出しがネストしていて読みづらいのでちょっと考えてみた。
ついでに破壊的にリストが操作されるのもどうにかした。
[ソース]
let s:algorithms = { "__list" : [] } function! s:algorithms.list() dict return self.__list endfunction function! s:as_list(list) let s:algorithms.__list = deepcopy(a:list) return s:algorithms endfunction function! s:algorithms.sort() dict call sort(self.list()) return self endfunction function! s:algorithms.reverse() dict call reverse(self.list()) return self endfunction function! s:algorithms.filter(expr) dict call filter(self.list(), a:expr) return self endfunction function! s:algorithms.size() dict return len(self.list()) endfunction function! s:algorithms.map(expr) dict call map(self.list(), a:expr) return self endfunction let array = [2, 5, 1, 7, 3, 4, 9, 0, 8, 1] echo "元の list" echo array echo "偶数を降順にソートして、2倍にする" echo s:as_list(array).filter("v:val % 2 == 0").sort().reverse().map("v:val + v:val").list() echo "操作後の list" echo array echo "通常の組み込み関数で操作すると" echo map(reverse(sort(filter(array, "v:val % 2 == 0"))), "v:val + v:val") echo "list が破壊的に変更される" echo array
[出力]
元の list [2, 5, 1, 7, 3, 4, 9, 0, 8, 1] 偶数を降順にソートして、2倍にする [16, 8, 4, 0] 操作後の list [2, 5, 1, 7, 3, 4, 9, 0, 8, 1] 通常の組み込み関数だと [16, 8, 4, 0] list が破壊的に変更される [16, 8, 4, 0]
こんな感じです。
実装自体は、各々のリスト操作を辞書で定義しているだけですね。
あとはリストへの操作を次々と呼びだしています。
as_list がちょっとかっこ悪いけど、下の方に書かれている一般的(?)な書き方と比べるとまだ分かりやすいんじゃないかなーと。
こっちの方もぼちぼちライブラリ化していきたい所です。