I think we can get some interesting use cases if the index of v:val is
exposed during the map() execution, and I think we can reuse v:key for
that purpose. E.g., I have a use case in which, given a list of
increasing numbers, get a list of differences, so something like the
below will get it done:
:let l = [9, 17, 26, 36]
:echo map(l[1:], 'v:val-l[v:key]')
[8, 9, 10]
You could achieve the above using workarounds or using a for loop, but
is there anything wrong in using v:key for this purpose? The change
seems to be minimal, as the below patch worked fine for me:
Index: C:/src/vim7/src/eval.c
===================================================================
--- C:/src/vim7/src/eval.c (revision 1586)
+++ C:/src/vim7/src/eval.c (working copy)
@@ -7768,7 +7768,6 @@
{"tabpagenr", 0, 1, f_tabpagenr},
{"tabpagewinnr", 1, 2, f_tabpagewinnr},
{"tagfiles", 0, 0, f_tagfiles},
- {"taglist", 1, 1, f_taglist},
{"tempname", 0, 0, f_tempname},
{"test", 1, 1, f_test},
{"tolower", 1, 1, f_tolower},
@@ -9920,6 +9919,7 @@
int todo;
char_u *ermsg = map ? (char_u *)"map()" : (char_u *)"filter()";
int save_did_emsg;
+ int index = 0;
if (argvars[0].v_type == VAR_LIST)
{
@@ -9953,9 +9953,9 @@
save_did_emsg = did_emsg;
did_emsg = FALSE;
+ prepare_vimvar(VV_KEY, &save_key);
if (argvars[0].v_type == VAR_DICT)
{
- prepare_vimvar(VV_KEY, &save_key);
vimvars[VV_KEY].vv_type = VAR_STRING;
ht = &d->dv_hashtab;
@@ -9979,23 +9979,26 @@
}
}
hash_unlock(ht);
-
- restore_vimvar(VV_KEY, &save_key);
}
else
{
+ vimvars[VV_KEY].vv_type = VAR_NUMBER;
+
for (li = l->lv_first; li != NULL; li = nli)
{
if (tv_check_lock(li->li_tv.v_lock, ermsg))
break;
nli = li->li_next;
+ vimvars[VV_KEY].vv_nr = index;
if (filter_map_one(&li->li_tv, expr, map, &rem) == FAIL
|| did_emsg)
break;
if (!map && rem)
listitem_remove(l, li);
+ ++index;
}
}
+ restore_vimvar(VV_KEY, &save_key);
restore_vimvar(VV_VAL, &save_val);
Index: C:/src/vim7/runtime/doc/eval.txt
===================================================================
--- C:/src/vim7/runtime/doc/eval.txt (revision 1586)
+++ C:/src/vim7/runtime/doc/eval.txt (working copy)
@@ -3802,7 +3802,8 @@
Replace each item in {expr} with the result of evaluating
{string}.
Inside {string} |v:val| has the value of the current item.
- For a |Dictionary| |v:key| has the key of the current item.
+ For a |Dictionary| |v:key| has the key of the current item
+ and for a |List| |v:key| has the index of the current item.
Example: >
:call map(mylist, '"> " . v:val . " <"')
< This puts "> " before and " <" after each item in "mylist".
I have tested to make sure v:key continues to work as expected for dictionaries.
Bram, if the above patch is acceptable, I would really appreciate if
you could include it.
--
Thanks,
Hari
--~--~---------~--~----~------------~-------~--~----~
You received this message from the "vim_dev" maillist.
For more information, visit http://www.vim.org/maillist.php
-~----------~----~----~----~------~----~------~--~---