> How about separating it from sort()? That is, an uniq() function
>
> that would remove duplicates from an already sorted list (results would
>
> be undefined if the input list is not sorted). That would be consistent
>
> with how uniq(1) works on UNIX.
This patch add uniq() function. uniq(list) will remove copies of repeated
adjacent items
--
--
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php
---
You received this message because you are subscribed to the Google Groups
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.
diff -r 70fac246bfe4 runtime/doc/change.txt
--- a/runtime/doc/change.txt Wed Mar 19 18:57:54 2014 +0100
+++ b/runtime/doc/change.txt Fri Mar 21 21:36:11 2014 +0700
@@ -1650,7 +1650,7 @@
7. Sorting text *sorting*
Vim has a sorting function and a sorting command. The sorting function can be
-found here: |sort()|.
+found here: |sort()|, |uniq()|.
*:sor* *:sort*
:[range]sor[t][!] [i][u][r][n][x][o] [/{pattern}/]
diff -r 70fac246bfe4 runtime/doc/eval.txt
--- a/runtime/doc/eval.txt Wed Mar 19 18:57:54 2014 +0100
+++ b/runtime/doc/eval.txt Fri Mar 21 21:36:11 2014 +0700
@@ -327,6 +327,7 @@
Changing the order of items in a list: >
:call sort(list) " sort a list alphabetically
:call reverse(list) " reverse the order of items
+ :call uniq(sort(list)) " sort and remove duplicates
For loop ~
@@ -2005,6 +2006,8 @@
type( {name}) Number type of variable {name}
undofile( {name}) String undo file name for {name}
undotree() List undo file tree
+uniq( {list} [, {func} [, {dict}]])
+ List remove adjacent duplicates
values( {dict}) List values in {dict}
virtcol( {expr}) Number screen column of cursor or mark
visualmode( [expr]) String last visual mode used
@@ -6169,6 +6172,14 @@
blocks. Each item may again have an "alt"
item.
+uniq({list} [, {func} [, {dict}]]) *uniq()* *E702*
+ Remove second and succeeding copies of repeated adjacent
+ {list} items in-place. Returns {list}. If you want a list
+ to remain unmodified make a copy first: >
+ :let newlist = uniq(copy(mylist))
+< Compare function uses the string representation of each item.
+ For the use of {func} and {dict} see |sort()|.
+
values({dict}) *values()*
Return a |List| with all the values of {dict}. The |List| is
in arbitrary order.
diff -r 70fac246bfe4 runtime/doc/usr_41.txt
--- a/runtime/doc/usr_41.txt Wed Mar 19 18:57:54 2014 +0100
+++ b/runtime/doc/usr_41.txt Fri Mar 21 21:36:11 2014 +0700
@@ -623,6 +623,7 @@
map() change each List item
sort() sort a List
reverse() reverse the order of a List
+ uniq() remove copies of repeated adjacent items
split() split a String into a List
join() join List items into a String
range() return a List with a sequence of numbers
diff -r 70fac246bfe4 runtime/doc/version7.txt
--- a/runtime/doc/version7.txt Wed Mar 19 18:57:54 2014 +0100
+++ b/runtime/doc/version7.txt Fri Mar 21 21:36:11 2014 +0700
@@ -942,6 +942,7 @@
|tagfiles()| List with tags file names
|taglist()| get list of matching tags (Yegappan Lakshmanan)
|tr()| translate characters (Ron Aaron)
+|uniq()| remove copies of repeated adjacent list items
|values()| get List of Dictionary values
|winnr()| takes an argument: what window to use
|winrestview()| restore the view of the current window
diff -r 70fac246bfe4 src/eval.c
--- a/src/eval.c Wed Mar 19 18:57:54 2014 +0100
+++ b/src/eval.c Fri Mar 21 21:36:11 2014 +0700
@@ -744,6 +744,7 @@
static void f_type __ARGS((typval_T *argvars, typval_T *rettv));
static void f_undofile __ARGS((typval_T *argvars, typval_T *rettv));
static void f_undotree __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_uniq __ARGS((typval_T *argvars, typval_T *rettv));
static void f_values __ARGS((typval_T *argvars, typval_T *rettv));
static void f_virtcol __ARGS((typval_T *argvars, typval_T *rettv));
static void f_visualmode __ARGS((typval_T *argvars, typval_T *rettv));
@@ -8150,6 +8151,7 @@
{"type", 1, 1, f_type},
{"undofile", 1, 1, f_undofile},
{"undotree", 0, 0, f_undotree},
+ {"uniq", 1, 3, f_uniq},
{"values", 1, 1, f_values},
{"virtcol", 1, 1, f_virtcol},
{"visualmode", 0, 1, f_visualmode},
@@ -17035,7 +17037,7 @@
#define ITEM_COMPARE_FAIL 999
/*
- * Compare functions for f_sort() below.
+ * Compare functions for f_sort() and f_uniq() below.
*/
static int
#ifdef __BORLANDC__
@@ -18728,6 +18730,112 @@
}
/*
+ * "uniq({list})" function
+ */
+ static void
+f_uniq(argvars, rettv)
+ typval_T *argvars;
+ typval_T *rettv;
+{
+ list_T *l;
+ listitem_T *li1, *li2;
+ long len;
+ long i;
+ int r;
+ int error = FALSE;
+
+ if (argvars[0].v_type != VAR_LIST)
+ EMSG2(_(e_listarg), "uniq()");
+ else
+ {
+ l = argvars[0].vval.v_list;
+ if (l == NULL || tv_check_lock(l->lv_lock,
+ (char_u *)_("uniq() argument")))
+ return;
+ rettv->vval.v_list = l;
+ rettv->v_type = VAR_LIST;
+ ++l->lv_refcount;
+
+ len = list_len(l);
+ if (len <= 1)
+ return;
+
+ item_compare_ic = FALSE;
+ item_compare_func = NULL;
+ item_compare_selfdict = NULL;
+ if (argvars[1].v_type != VAR_UNKNOWN)
+ {
+ /* optional second argument: {func} */
+ if (argvars[1].v_type == VAR_FUNC)
+ item_compare_func = argvars[1].vval.v_string;
+ else
+ {
+ i = get_tv_number_chk(&argvars[1], &error);
+ if (error)
+ return; /* type error; errmsg already given */
+ if (i == 1)
+ item_compare_ic = TRUE;
+ else
+ item_compare_func = get_tv_string(&argvars[1]);
+ }
+
+ if (argvars[2].v_type != VAR_UNKNOWN)
+ {
+ /* optional third argument: {dict} */
+ if (argvars[2].v_type != VAR_DICT)
+ {
+ EMSG(_(e_dictreq));
+ return;
+ }
+ item_compare_selfdict = argvars[2].vval.v_dict;
+ }
+ }
+
+ item_compare_func_err = FALSE;
+ /* test the compare function */
+ li1 = l->lv_first;
+ li2 = li1->li_next;
+ if (item_compare_func != NULL
+ && item_compare2((void *)&li1, (void *)&li2)
+ == ITEM_COMPARE_FAIL)
+ EMSG(_("E702: Uniq compare function failed"));
+ else
+ {
+ /* Compare item by item */
+ li1 = l->lv_first;
+ li2 = li1->li_next;
+ for (i = 0; i < len-1; ++i)
+ {
+ if (item_compare_func)
+ {
+ r = item_compare2((void *)&li1, (void *)&li2);
+ }
+ else
+ {
+ r = item_compare((void *)&li1, (void *)&li2);
+ }
+ if (item_compare_func_err)
+ break;
+ if (r == 0)
+ {
+ /* remove duplicate */
+ li1->li_next = li2->li_next;
+ list_fix_watch(l, li2);
+ listitem_free(li2);
+ l->lv_len--;
+ li2 = li1->li_next;
+ }
+ else
+ {
+ li1 = li1->li_next;
+ li2 = li1->li_next;
+ }
+ }
+ }
+ }
+}
+
+/*
* "values(dict)" function
*/
static void
diff -r 70fac246bfe4 src/testdir/test55.in
--- a/src/testdir/test55.in Wed Mar 19 18:57:54 2014 +0100
+++ b/src/testdir/test55.in Fri Mar 21 21:36:11 2014 +0700
@@ -323,13 +323,15 @@
: $put ='caught ' . v:exception
:endtry
:"
-:" reverse() and sort()
-:let l = ['-0', 'A11', 2, 'xaaa', 4, 'foo', 'foo6', [0, 1, 2], 'x8']
+:" reverse(), sort(), uniq()
+:let l = ['-0', 'A11', 2, 2, 'xaaa', 4, 'foo', 'foo6', 'foo', [0, 1, 2], 'x8',
[0, 1, 2], 1.5]
+:$put =string(uniq(copy(l)))
:$put =string(reverse(l))
:$put =string(reverse(reverse(l)))
:$put =string(sort(l))
:$put =string(reverse(sort(l)))
:$put =string(sort(reverse(sort(l))))
+:$put =string(uniq(sort(l)))
:"
:" splitting a string to a List
:$put =string(split(' aa bb '))
diff -r 70fac246bfe4 src/testdir/test55.ok
--- a/src/testdir/test55.ok Wed Mar 19 18:57:54 2014 +0100
+++ b/src/testdir/test55.ok Fri Mar 21 21:36:11 2014 +0700
@@ -94,11 +94,13 @@
caught a:000[2]
caught a:000[3]
[1, 2, [3, 9, 5, 6], {'a': 12, '5': 8}]
-['x8', [0, 1, 2], 'foo6', 'foo', 4, 'xaaa', 2, 'A11', '-0']
-['x8', [0, 1, 2], 'foo6', 'foo', 4, 'xaaa', 2, 'A11', '-0']
-['-0', 'A11', 'foo', 'foo6', 'x8', 'xaaa', 2, 4, [0, 1, 2]]
-[[0, 1, 2], 4, 2, 'xaaa', 'x8', 'foo6', 'foo', 'A11', '-0']
-['-0', 'A11', 'foo', 'foo6', 'x8', 'xaaa', 2, 4, [0, 1, 2]]
+['-0', 'A11', 2, 'xaaa', 4, 'foo', 'foo6', 'foo', [0, 1, 2], 'x8', [0, 1, 2],
1.5]
+[1.5, [0, 1, 2], 'x8', [0, 1, 2], 'foo', 'foo6', 'foo', 4, 'xaaa', 2, 2,
'A11', '-0']
+[1.5, [0, 1, 2], 'x8', [0, 1, 2], 'foo', 'foo6', 'foo', 4, 'xaaa', 2, 2,
'A11', '-0']
+['-0', 'A11', 'foo', 'foo', 'foo6', 'x8', 'xaaa', 1.5, 2, 2, 4, [0, 1, 2], [0,
1, 2]]
+[[0, 1, 2], [0, 1, 2], 4, 2, 2, 1.5, 'xaaa', 'x8', 'foo6', 'foo', 'foo',
'A11', '-0']
+['-0', 'A11', 'foo', 'foo', 'foo6', 'x8', 'xaaa', 1.5, 2, 2, 4, [0, 1, 2], [0,
1, 2]]
+['-0', 'A11', 'foo', 'foo6', 'x8', 'xaaa', 1.5, 2, 4, [0, 1, 2]]
['aa', 'bb']
['aa', 'bb']
['', 'aa', 'bb', '']