0
0
mirror of https://github.com/vim/vim.git synced 2025-09-26 04:04:07 -04:00

patch 7.4.951

Problem:    Sorting number strings does not work as expected. (Luc Hermitte)
Solution:   Add the 'N" argument to sort()
This commit is contained in:
Bram Moolenaar
2015-12-03 16:33:12 +01:00
parent 4649ded287
commit b00da1d6d1
6 changed files with 52 additions and 1 deletions

View File

@@ -5803,6 +5803,10 @@ sort({list} [, {func} [, {dict}]]) *sort()* *E702*
strtod() function to parse numbers, Strings, Lists, Dicts and
Funcrefs will be considered as being 0).
When {func} is given and it is 'N' then all items will be
sorted numerical. This is like 'n' but a string containing
digits will be used as the number they represent.
When {func} is a |Funcref| or a function name, this function
is called to compare items. The function is invoked with two
items as argument and must return zero if they are equal, 1 or
@@ -5817,6 +5821,11 @@ sort({list} [, {func} [, {dict}]]) *sort()* *E702*
on numbers, text strings will sort next to each other, in the
same order as they were originally.
The sort is stable, items which compare equal (as number or as
string) will keep their relative position. E.g., when sorting
on numbers, text strings will sort next to each other, in the
same order as they were originally.
Also see |uniq()|.
Example: >

View File

@@ -17928,6 +17928,7 @@ typedef struct
static int item_compare_ic;
static int item_compare_numeric;
static int item_compare_numbers;
static char_u *item_compare_func;
static dict_T *item_compare_selfdict;
static int item_compare_func_err;
@@ -17958,6 +17959,15 @@ item_compare(s1, s2)
si2 = (sortItem_T *)s2;
tv1 = &si1->item->li_tv;
tv2 = &si2->item->li_tv;
if (item_compare_numbers)
{
long v1 = get_tv_number(tv1);
long v2 = get_tv_number(tv2);
return v1 == v2 ? 0 : v1 > v2 ? 1 : -1;
}
/* tv2string() puts quotes around a string and allocates memory. Don't do
* that for string variables. Use a single quote when comparing with a
* non-string to do what the docs promise. */
@@ -18091,6 +18101,7 @@ do_sort_uniq(argvars, rettv, sort)
item_compare_ic = FALSE;
item_compare_numeric = FALSE;
item_compare_numbers = FALSE;
item_compare_func = NULL;
item_compare_selfdict = NULL;
if (argvars[1].v_type != VAR_UNKNOWN)
@@ -18116,6 +18127,11 @@ do_sort_uniq(argvars, rettv, sort)
item_compare_func = NULL;
item_compare_numeric = TRUE;
}
else if (STRCMP(item_compare_func, "N") == 0)
{
item_compare_func = NULL;
item_compare_numbers = TRUE;
}
else if (STRCMP(item_compare_func, "i") == 0)
{
item_compare_func = NULL;

View File

@@ -69,7 +69,7 @@ SCRIPTS = test1.out test2.out test3.out test4.out test5.out test6.out \
test_writefile.out
NEW_TESTS = test_assert.res \
test_undolevels.res
test_alot.res
SCRIPTS_GUI = test16.out

View File

@@ -0,0 +1,5 @@
" A series of tests that can run in one Vim invocation.
" This makes testing go faster, since Vim doesn't need to restart.
source test_undolevels.vim
source test_sort.vim

19
src/testdir/test_sort.vim Normal file
View File

@@ -0,0 +1,19 @@
" Test sort()
func Test_sort_strings()
" numbers compared as strings
call assert_equal([1, 2, 3], sort([3, 2, 1]))
call assert_equal([13, 28, 3], sort([3, 28, 13]))
endfunc
func Test_sort_numeric()
call assert_equal([1, 2, 3], sort([3, 2, 1], 'n'))
call assert_equal([3, 13, 28], sort([13, 28, 3], 'n'))
" strings are not sorted
call assert_equal(['13', '28', '3'], sort(['13', '28', '3'], 'n'))
endfunc
func Test_sort_numbers()
call assert_equal([3, 13, 28], sort([13, 28, 3], 'N'))
call assert_equal(['3', '13', '28'], sort(['13', '28', '3'], 'N'))
endfunc

View File

@@ -741,6 +741,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
951,
/**/
950,
/**/