Reputation: 34373
Experimenting with vimscript and reading the wonderful Learn Vimscript the Hard Way (LVTHW), I realized that Vim wasn't sorting numbers the way I wanted it to.
For example this function from LVTHW
function! Sorted(l)
let new_list = deepcopy(a:l)
call sort(new_list)
return new_list
endfunction
surprised me when I called it with Sorted([3, 1, 11, 2])
:
It returned [1, 11, 2, 3]
.
I think Vim sorts those numbers in alphabetical order. But I'd expect the function to return the numbers in natural order:
[1, 2, 3, 11]
How can I convince Vim (7.4) to do that?
Upvotes: 1
Views: 791
Reputation: 195169
if you've read the help doc of sort()
function, you 'll see that you can give a n
to {func}
parameter to let sort do numerical sorting:
example:
:echo sort([3,1,11,2],'n')
[1, 2, 3, 11]
Upvotes: 1
Reputation: 34373
The trick is to pass Vim's sort
a comparator function, which in my case I called NaturalOrder
.
" Sorts numbers in ascending order.
" Examples:
" [2, 3, 1, 11, 2] --> [1, 2, 2, 3, 11]
" ['2', '1', '10','-1'] --> [-1, 1, 2, 10]
function! Sorted(list)
" Make sure the list consists of numbers (and not strings)
" This also ensures that the original list is not modified
let nrs= ToNrs(a:list)
let sortedList = sort(nrs, "NaturalOrder")
echo sortedList
return sortedList
endfunction
" Comparator function for natural ordering of numbers
function! NaturalOrder(firstNr, secondNr)
if a:firstNr < a:secondNr
return -1
elseif a:firstNr > a:secondNr
return 1
else
return 0
endif
endfunction
" Coerces every element of a list to a number. Returns a new list without
" modifying the original list.
function! ToNrs(list)
let nrs = []
for elem in a:list
let nr = 0 + elem
call add(nrs, nr)
endfor
return nrs
endfunction
Upvotes: 0