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
-~----------~----~----~----~------~----~------~--~---

Raspunde prin e-mail lui