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

Hi

  • I need help with the following bit of code
  • @ex_array = qw(sample1:3,4,5 sample2:5,7,8 sample3 sample4:6,9,0)
    foreach $sy (@ex_arrya) { %cp_samp=map {$_} split/:/, $sy; }
  • With this i get a hash
  • $cp_samp{sample1} = 3,4,5.

    Well, how do i split the comma separated values and store it as separate hash values, so i'll be able to access them separately ?

  • I need :
  • $cp_samp{sample1}{first}=3 $cp_samp{sample1}{second}=4 ..

  • Is it possible to include this in the map command used above ?
  • Thanks

    Replies are listed 'Best First'.
    Re: create hash with map
    by ikegami (Patriarch) on Sep 24, 2007 at 08:34 UTC

      %cp_samp=map {$_} split/:/, $sy;
      is the same thing as
      %cp_samp=split/:/, $sy;

      foreach $sy (@ex_array) { %cp_samp=map {$_} split/:/, $sy; }
      is the same thing as
      %cp_samp=split/:/, $ex_array[-1] if @ex_array;
      which produces neither what you want nor what you said is produced.

      Finally, may I recommend a HoA ($cp_samp{sample1}[0]=3 $cp_samp{sample1}[1]=4 ..) instead of a HoH?

      my %cp = map { my ($label, $list) = (split(/:/), ''); $label => [ split /,/, $list ] } @ex;

      Update: By the way, the for version would be

      my %cp; foreach (@ex) { my ($label, $list) = (split(/:/), ''); $cp{$label} = [ split /,/, $list ]; }

        That was quick and works great for me !!

        Thanks ikegami !!
    Re: create hash with map
    by mwah (Hermit) on Sep 24, 2007 at 14:59 UTC
      In Addition to ikegamis solution, you
      might use:
      # |hash key| [hash val: array(comma sep values)] %cp_samp = map{ (split ':')[0], [split ',', (split ':')[1] ] }@ex_ar +ray; # display result with: print map "$_ => array [ @{ $cp_samp{$_} } ]\n", keys %cp_samp;
      Regards
      M.

        That gives

        Use of uninitialized value in split

        Fix:

        %cp = map{ (split /:/)[0], [split /,/, ((split /:/), '')[1] ] } @ex;

        Note that using a string as the first argument of split is misleading, since it expects a regexp. You might as well provide a regexp directly.


           Use of uninitialized value in split

          Depending on the input data (if inconsistent)
          this might happen but doesnt't do any harm
          to the whole thing

          In order to sanitize the stuff, one has to check
          for the existence of the second split field after
          the ':'
          Just by substitution of (split...)[1] with (split ...)[-1]
          a workaroud is found
          %cp_samp = map{ (split ':')[0],  [split ',', (split ':')[-1] ] }@ex_array;
          (corrected, see below ... sorry)

          or even

          %cp_samp = map{ (split /:/)[0], [split /,/,  ( (split /:/)[1] || '')] }@ex_array;

          But this is sth. I'd like the OP to have figured out ...

          Regards
          M.
            A reply falls below the community's threshold of quality. You may see it by logging in.