" 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