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:
@@ -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: >
|
||||
|
16
src/eval.c
16
src/eval.c
@@ -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;
|
||||
|
@@ -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
|
||||
|
||||
|
5
src/testdir/test_alot.vim
Normal file
5
src/testdir/test_alot.vim
Normal 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
19
src/testdir/test_sort.vim
Normal 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
|
@@ -741,6 +741,8 @@ static char *(features[]) =
|
||||
|
||||
static int included_patches[] =
|
||||
{ /* Add new patch number below this line */
|
||||
/**/
|
||||
951,
|
||||
/**/
|
||||
950,
|
||||
/**/
|
||||
|
Reference in New Issue
Block a user