" list#flat([elem, ...]) {{{1 " " Flatten the arguments into a single list. " " given: a = ['a', 'b'] " b = [1, 2] " list#flat(a,b) : ['a', 'b', 1, 2] " function! list#flat(...) let fl = [] let list = a:000 if a:0 == 1 let list = list[0] endif for el in list if type(el) == type([]) call extend(fl, list#flat(el)) else call extend(fl, [el]) endif unlet el endfor return fl endfunction function! list#split(list, match) let ret = [] let r = [] for e in a:list if e =~ a:match call add(ret, r) let r = [] else call add(r, e) endif endfor call add(ret, r) return ret endfunction " list#zip(list_a, list_b, method) {{{1 " " Join each element of list_a with the corresponding element of list_b " Use the third argument, method, to dictate how the elements should be " combined: " given: a = [a, b] " b = [1, 2] " 0 = flattened list : [a, 1, b, 2] " 1 = list groups : [[a, 1], [b, 2]] " x = join separator x : [ax1, bx2] " " NOTE: If one list is longer than the other, the tail of that list is added " to the result. function! list#zip(a, b, ...) let method = 1 if a:0 let method = a:1 endif let i = 0 let r = [] let l_a = len(a:a) let l_b = len(a:b) let n = min([len(a:a), len(a:b)]) while i < n if method == "0" call add(r, a:a[i]) call add(r, a:b[i]) elseif method == "1" call add(r, [a:a[i], a:b[i]]) else call add(r, join([a:a[i], a:b[i]], method)) endif let i+= 1 endwhile if l_a == l_b return r elseif l_a > l_b exe "return r + a:a[" . n . ":]" else exe "return r + a:b[" . n . ":]" endif endfunction "}}}1 " list#inject(list, init, funcref) function! list#inject(list, init, funcref) if ! exists('*' . a:funcref) throw 'vimple: list#inject(): Funcref ' . a:funcref . ' does not exist!' return a:init elseif empty(a:list) return a:init else let i = a:list[0] let r = a:list[1:-1] let v = call(a:funcref, [a:init, i]) return list#inject(r, v, a:funcref) endif endf " partition list into count-element sublists function! list#partition(list, count) let lst = deepcopy(a:list) let len = len(lst) let cnt = a:count let newlists = [] if cnt <= 0 throw 'vimple: list#partition: count must be positive' endif if cnt >= len return lst endif for idx in range(0, len - 1, cnt) if cnt > len(lst) let cnt = len(lst) endif call add(newlists, remove(lst, 0, (cnt - 1))) endfor return newlists endfunc " partition list into cols sublists and join with colsep=\t " list#lspread(list, cols, colsep="\t") " returns a list function! list#lspread(list, cols, ...) let colsep = "\t" if a:0 let colsep = a:1 endif return map(list#partition(a:list, a:cols), 'join(v:val, "' . escape(colsep, '"') . '")') endfunction " partition list into cols sublists and join with col and row seps " list#spread(list, cols, colsep, rowsep) " returns a string function! list#spread(list, cols, ...) let colsep = "\t" let rowsep = "\n" if a:0 if a:0 == 2 let colsep = a:1 let rowsep = a:2 else let colsep = a:1 endif endif return join(list#lspread(a:list, a:cols, colsep), rowsep) endfunction " " map expr over each element of each sublist of list " function! list#lmap(list, expr) " return map(a:list, 'map(v:val, ''' . a:expr . ''')') " endfunction function! list#shuffle(a) let b = deepcopy(a:a) let n = 0 let length = len(b) while n < length let tmp = b[n] let dst = rng#rand() % length let b[n] = b[dst] let b[dst] = tmp let n += 1 endwhile return b endfunction " list#paste(a, b, join, sep) " Emulate the unix paste command " Arguments: " a - each of 'a' and 'b' are lists, or " b - strings containing 'sep' (default='\n') delimited elements " join - separator (default=' ') to use when joining each respective line of " a and b " sep - separator (default='\n') to use when splitting a and b (if strings) " e.g. " ------v yank following into register a - "a3yy " one " two " three " ------v yank following into register b - "b3yy " satu " dua " tiga " call append('.', Paste(@a, @b)) function! list#paste(a, b, ...) let join = (a:0 >= 1) ? a:1 : ' ' let sep = (a:0 == 2) ? a:2 : '\n' if type(a:a) == 1 let a = split(a:a, sep) let b = split(a:b, sep) else let a = a:a let b = a:b end return list#zip(a, b, join) endfunction " list#lrotate(array) " Perform a Left Rotate on array function! list#lrotate(a) return extend(a:a[1:-1], [a:a[0]]) endfunction " list#rrotate(array) " Perform a Right Rotate on array function! list#rrotate(a) return extend([a:a[-1]], a:a[0:-2]) endfunction