created 2006 · complexity intermediate · author Salman Halim · version 7.0
Vim 7 has a built-in function called sort() that takes a List and an optional comparator. It works really well, but unlike the Vim 7 command :sort, there is no way to have the function remove duplicates from the list. Hence, this function:
" Works like sort(), optionally taking in a comparator (just like the
" original), except that duplicate entries will be removed.
function! SortUnique( list, ... )
let dictionary = {}
for i in a:list
execute "let dictionary[ '" . i . "' ] = ''"
endfor
let result = []
if ( exists( 'a:1' ) )
let result = sort( keys( dictionary ), a:1 )
else
let result = sort( keys( dictionary ) )
endif
return result
endfunction
Call it just like you would sort(). Note that because it removes duplicate entries, the return List isn't necessarily going to be the same size as the original. Furthermore, unlike sort(), this can't do things in place. To replace the original List, do this:
let theList = SortUnique( theList )
References[]
See also[]
- Uniq - Removing duplicate lines remove duplicate lines (not items in a List)
Comments[]
This implementation loose the initial type of the list elements when it transforms them into strings. Is see two possible corrections:
- one that first applies the sort(), and then implements the unique by hand
- pro: it may be the fastest solution if there aren't many redundant elements
function! list#unique_sort2(list, ...)
let list = copy(a:list)
if ( exists( 'a:1' ) )
call sort(list, a:1 )
else
call sort(list)
endif
if len(list) <= 1 | return list | endif
let result = [ list[0] ]
let last = list[0]
let i = 1
while i < len(list)
if last != list[i]
call add(result, list[i])
endif
let last = list[i]
let i += 1
endwhile
return result
endfunction
- one that fixes previous code
- pro: it should be the fastest solution if there are many redundant elements.
function! list#unique_sort(list, ...)
let dictionary = {}
for i in a:list
let dictionary[string(i)] = i
endfor
let result = []
if ( exists( 'a:1' ) )
let result = sort( values( dictionary ), a:1 )
else
let result = sort( values( dictionary ) )
endif
return result
endfunction
NB: This function should also receive another (optional) parameter than defines what being equal means.
--Luc Hermitte 16:54, 23 April 2008 (UTC)