Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

You have a string x:q,y:u,z:n How to create a hash from this string x=>q y=>u z=>n

Replies are listed 'Best First'.
Re: How to create a hash from string
by choroba (Cardinal) on Aug 09, 2013 at 11:00 UTC
    I am not sure whether the sqare brackets are part of the input. The following code works for both alternatives. It uses the fact that a hash can be created from a list by just interpreting each odd element as a key and each even element as its value.
    #!/usr/bin/perl use warnings; use strict; use Data::Dumper; my $string = 'x:q,y:u,z:n'; my %hash = split /[:,]/, $string; print Dumper \%hash; $string = '[x:q,y:u,z:n]'; %hash = split /[:,]/, substr $string, 1, -1; print Dumper \%hash;
    لսႽ† ᥲᥒ⚪⟊Ⴙᘓᖇ Ꮅᘓᖇ⎱ Ⴙᥲ𝇋ƙᘓᖇ
Re: How to create a hash from string
by Tux (Canon) on Aug 09, 2013 at 11:22 UTC

    Both given answers are fine, but this smells like records embedded in CSV, where both answers will soon fail. What if x is allowed to be «This, my friend, is why : is allowed in "text" to fail»?

    update: additional remarks:

    In case that cannot happen, stick to the earlier answer. They are fast and simple. In case it /can/ happen, you need a double CSV parser. The first to split on , the second on ::

    my $outer = Text::CSV_XS->new ({ binary => 1, auto_diag => 1 }); my $inner = Text::CSV_XS->new ({ binary => 1, auto_diag => 1, sep_char + => ":" }); my %hash; while (my $row = $outer->getline ($fh)) { foreach (@$row) { $inner->parse ($_); my @f = $inner->fields; if (@f >= 2) { # assuming key:value:1 will result in $hash{key +} = "value:1" my $key = shift @f; $hash{$key} = join ":" => @f; } else { warn "Probably not a key-value pair '$_'"; } } }

    which is likely to get more and more complicated as you proceed.


    Enjoy, Have FUN! H.Merijn
Re: How to create a hash from string
by 2teez (Vicar) on Aug 09, 2013 at 11:08 UTC

    Or this:

    use warnings; use strict; use Data::Dumper; my %h = map $_ => split/:|,/ => 'x:q,y:u,z:n'; { local $Data::Dumper::Sortkeys = 1; ## Update print Dumper \%h; }
    UPDATE:
    In the solution, map is not even needed. Without it, you still have your solution.
    choroba caught that!

    If you tell me, I'll forget.
    If you show me, I'll remember.
    if you involve me, I'll understand.
    --- Author unknown to me