from lines to dict keys

View: New views
14 Messages — Rating Filter:   Alert me  

from lines to dict keys

by Marc Chantreux-3 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


hello guys,

i want each lines of the output of a shell command to become a key of a
dict. I wote this code:

let t = {}
for k in split( system("echo foo; echo bar "), '\n' )
    let t[k] = 1
endfor

but i don't like it: as the loop is here to populate the dictionnary, i
would like to use something more appropriate. In perl for exemple, the
map function enables you to write

my %a = map { $_ => 1 } split /\n/, qx< echo foo; echo bar>

vim has the equivalent of $_: it's called v:val, so i tried to use map
or filter with attempts looking like that:

let t = map( split( system("echo foo; echo bar "), '\n' ), { v:val : 1 } )

and yet i just wonder if it's possible.

regards,
marc

--~--~---------~--~----~------------~-------~--~----~
You received this message from the "vim_use" maillist.
For more information, visit http://www.vim.org/maillist.php
-~----------~----~----~----~------~----~------~--~---


Re: from lines to dict keys

by Andy Wokula :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


Marc Chantreux schrieb:

> hello guys,
>
> i want each lines of the output of a shell command to become a key of a
> dict. I wote this code:
>
> let t = {}
> for k in split( system("echo foo; echo bar "), '\n' )
>     let t[k] = 1
> endfor
>
> but i don't like it: as the loop is here to populate the dictionnary, i
> would like to use something more appropriate. In perl for exemple, the
> map function enables you to write
>
> my %a = map { $_ => 1 } split /\n/, qx< echo foo; echo bar>
>
> vim has the equivalent of $_: it's called v:val, so i tried to use map
> or filter with attempts looking like that:
>
> let t = map( split( system("echo foo; echo bar "), '\n' ), { v:val : 1 } )
>
> and yet i just wonder if it's possible.
>
> regards,
> marc

It is possible, the second argument to map() must be a string:
    :h map()
    :let t = map(["foo", "bar"], '{v:val : 1}')

--
Andy

--~--~---------~--~----~------------~-------~--~----~
You received this message from the "vim_use" maillist.
For more information, visit http://www.vim.org/maillist.php
-~----------~----~----~----~------~----~------~--~---


Re: from lines to dict keys

by Marc Chantreux-3 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


hello Andy and thanks for reply.

On Mon, Nov 09, 2009 at 06:33:24PM +0100, Andy Wokula wrote:
> It is possible, the second argument to map() must be a string:
>     :h map()
>     :let t = map(["foo", "bar"], '{v:val : 1}')

i tried this solution but the result is

[{'foo': 1}, {'bar': 1}]

when i expect

{'foo': 1, 'bar': 1 }

regards

marc

--~--~---------~--~----~------------~-------~--~----~
You received this message from the "vim_use" maillist.
For more information, visit http://www.vim.org/maillist.php
-~----------~----~----~----~------~----~------~--~---


Re: from lines to dict keys

by Andy Wokula :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


Marc Chantreux schrieb:

> hello Andy and thanks for reply.
>
> On Mon, Nov 09, 2009 at 06:33:24PM +0100, Andy Wokula wrote:
>> It is possible, the second argument to map() must be a string:
>>     :h map()
>>     :let t = map(["foo", "bar"], '{v:val : 1}')
>
> i tried this solution but the result is
>
> [{'foo': 1}, {'bar': 1}]
>
> when i expect
>
> {'foo': 1, 'bar': 1 }
>
> regards
>
> marc

Sorry, I didn't understand (dunno Perl).
I think you can't do it so nicely in Vim, but you can try the
following:

" helper to keep the list unchanged (not required):
func! KeepVal(_)
    return v:val
endfunc

let in_list = ["foo", "bar"]
let out_dict = {}
call map(in_list, 'KeepVal(extend(out_dict, {v:val : 1}))')

" not so nice:
" - extra command for initialising out_dict
" - return value of map() is useless here

--
Andy

--~--~---------~--~----~------------~-------~--~----~
You received this message from the "vim_use" maillist.
For more information, visit http://www.vim.org/maillist.php
-~----------~----~----~----~------~----~------~--~---


Re: from lines to dict keys

by Christian Brabandt-3 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


On Tue, November 10, 2009 12:19 pm, Andy Wokula wrote:

> Sorry, I didn't understand (dunno Perl).
> I think you can't do it so nicely in Vim, but you can try the
> following:
>
> " helper to keep the list unchanged (not required):
> func! KeepVal(_)
>     return v:val
> endfunc
>
> let in_list = ["foo", "bar"]
> let out_dict = {}
> call map(in_list, 'KeepVal(extend(out_dict, {v:val : 1}))')

You don't need KeepVal():
:call map(copy(in_list), 'extend(out_dict, {v:val : 1})')

regards,
Christian


--~--~---------~--~----~------------~-------~--~----~
You received this message from the "vim_use" maillist.
For more information, visit http://www.vim.org/maillist.php
-~----------~----~----~----~------~----~------~--~---


Re: from lines to dict keys

by Andy Wokula :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


Christian Brabandt schrieb:

> On Tue, November 10, 2009 12:19 pm, Andy Wokula wrote:
>> Sorry, I didn't understand (dunno Perl).
>> I think you can't do it so nicely in Vim, but you can try the
>> following:
>>
>> " helper to keep the list unchanged (not required):
>> func! KeepVal(_)
>>     return v:val
>> endfunc
>>
>> let in_list = ["foo", "bar"]
>> let out_dict = {}
>> call map(in_list, 'KeepVal(extend(out_dict, {v:val : 1}))')
>
> You don't need KeepVal():
> :call map(copy(in_list), 'extend(out_dict, {v:val : 1})')

I just didn't like getting a list full of dict references.  And the
return value of map() will be less "junky".

--
Andy

--~--~---------~--~----~------------~-------~--~----~
You received this message from the "vim_use" maillist.
For more information, visit http://www.vim.org/maillist.php
-~----------~----~----~----~------~----~------~--~---


Re: from lines to dict keys

by Christian Brabandt-3 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


Hi Andy!

On Di, 10 Nov 2009, Andy Wokula wrote:

>
> Christian Brabandt schrieb:
> > On Tue, November 10, 2009 12:19 pm, Andy Wokula wrote:
> >> let in_list = ["foo", "bar"]
> >> let out_dict = {}
> >> call map(in_list, 'KeepVal(extend(out_dict, {v:val : 1}))')
> >
> > You don't need KeepVal():
> > :call map(copy(in_list), 'extend(out_dict, {v:val : 1})')
>
> I just didn't like getting a list full of dict references.  And the
> return value of map() will be less "junky".

Okay, how about

:let @_=string(map(copy(in_list), 'extend(out_dict, {v:val : 1})'))

regards,
Christian
--
  • EFI is this other Intel brain-damage (the first one being ACPI).
       Torvalds, Linus (2006-07-24).

--~--~---------~--~----~------------~-------~--~----~
You received this message from the "vim_use" maillist.
For more information, visit http://www.vim.org/maillist.php
-~----------~----~----~----~------~----~------~--~---


Re: from lines to dict keys

by Tom Link-3 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


> :let @_=string(map(copy(in_list), 'extend(out_dict, {v:val : 1})'))

I personally don't think it is a good idea to use map for iterating
over a list since it manipulates the list it is working on and returns
that transformed list.

Since vimscripts provides no high-order function to iterate over a
list without modifying it, what's wrong with a dull looking for-loop:

for k in list
 let dict[k] = 1
endfor


--~--~---------~--~----~------------~-------~--~----~
You received this message from the "vim_use" maillist.
For more information, visit http://www.vim.org/maillist.php
-~----------~----~----~----~------~----~------~--~---


Re: from lines to dict keys

by Tom Link-3 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


> what's wrong with a dull looking for-loop:

Okay, that was the original solution anyway. I'd say stick to it.
--~--~---------~--~----~------------~-------~--~----~
You received this message from the "vim_use" maillist.
For more information, visit http://www.vim.org/maillist.php
-~----------~----~----~----~------~----~------~--~---


Re: from lines to dict keys

by Andy Wokula :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


Tom Link schrieb:

>> :let @_=string(map(copy(in_list), 'extend(out_dict, {v:val : 1})'))
>
> I personally don't think it is a good idea to use map for iterating
> over a list since it manipulates the list it is working on and returns
> that transformed list.
>
> Since vimscripts provides no high-order function to iterate over a
> list without modifying it, what's wrong with a dull looking for-loop:
>
> for k in list
>  let dict[k] = 1
> endfor

Nothing, it's the best option ;)  But the OP already used that.

--
Andy

--~--~---------~--~----~------------~-------~--~----~
You received this message from the "vim_use" maillist.
For more information, visit http://www.vim.org/maillist.php
-~----------~----~----~----~------~----~------~--~---


Re: from lines to dict keys

by Tom Link-3 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


On 10 Nov., 13:30, Tom Link <micat...@...> wrote:
> > what's wrong with a dull looking for-loop:
>
> Okay, that was the original solution anyway. I'd say stick to it.

Sorry for the reply to self. If you really want to use map, you could
use:

exec 'let dict = {'. join(map(split(lines, "\n"), 'string(v:val) .":
1"'), ",") .'}'

You have to make sure the lines are unique.

--~--~---------~--~----~------------~-------~--~----~
You received this message from the "vim_use" maillist.
For more information, visit http://www.vim.org/maillist.php
-~----------~----~----~----~------~----~------~--~---


Re: from lines to dict keys

by Marc Chantreux-3 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


hello all

many thanks for you tries and replies. all of them where very
instructive.

i'll stick on the for-loop solution as it seems that functionnal
solutions are harder to read/debug in viml.

regards
marc

--~--~---------~--~----~------------~-------~--~----~
You received this message from the "vim_use" maillist.
For more information, visit http://www.vim.org/maillist.php
-~----------~----~----~----~------~----~------~--~---


Re: from lines to dict keys

by Hari Krishna Dara-3 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


On Tue, Nov 10, 2009 at 8:06 AM, Marc Chantreux <khatar@...> wrote:
>
> hello all
>
> many thanks for you tries and replies. all of them where very
> instructive.
>
> i'll stick on the for-loop solution as it seems that functionnal
> solutions are harder to read/debug in viml.

Since you seem to want a one liner, here is one:

let t=eval('{'.join(map(split(system("echo foo; echo bar"), "\n" ),
'"''".v:val."'': 1"'), ',').'}')

--
Hari
>
> regards
> marc
>
> >
>

--~--~---------~--~----~------------~-------~--~----~
You received this message from the "vim_use" maillist.
For more information, visit http://www.vim.org/maillist.php
-~----------~----~----~----~------~----~------~--~---


Re: from lines to dict keys

by Marc Chantreux-3 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


hello Hari


On Tue, Nov 10, 2009 at 10:11:46PM -0800, Hari Krishna Dara wrote:
> Since you seem to want a one liner, here is one:
>
> let t=eval('{'.join(map(split(system("echo foo; echo bar"), "\n" ),
> '"''".v:val."'': 1"'), ',').'}')

I want my code to be readable then short. it seems that viml isn't the
good langage for it. I stick on the for-loop :)

regards,
marc

--~--~---------~--~----~------------~-------~--~----~
You received this message from the "vim_use" maillist.
For more information, visit http://www.vim.org/maillist.php
-~----------~----~----~----~------~----~------~--~---