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

hey Monks

I have a string with sets of data, each set delimited by a #
$patterns="1 10 100 10 0 0 0 0#2 10 100 10 1 3 5 2#3 20 100 10 0 3 5 2 +";

I want to split that string on those #s then by individual <whitespaces> to generate an array of hashes. Populated by something like this.

push @patterns, { 'opens' => $opens, 'first' => $first, 'last' => $las +t, 'inc' => $inc, 'noise' => $noise, 'min' => $min, 'max' => $max, 'i +nc' => $inc}; #e.g $patterns[0] = [{'opens'} => 1, {'first'} => 10, {'last'} => 100, + {'inc'} => 10, {'noise'} => 0, {'min'} => 0, {'max'} => 0, {'inc'} = +> 0};

I could just assign each element in the string its own variable during the splitting process, but was hoping someone cared to offer up something a little more clever?

thanks
conal.

Replies are listed 'Best First'.
Re: Help creating a data structure out of a delimited string
by toolic (Bishop) on Dec 15, 2010 at 18:12 UTC
    use warnings; use strict; use Data::Dumper; my @names = qw(opens first last inc noise min max inc); my $patterns = "1 10 100 10 0 0 0 0#2 10 100 10 1 3 5 2#3 20 100 10 0 +3 5 2"; my @data; for my $set (split /#/, $patterns) { my @vals = split /\s+/, $set; my %hash; for my $i (0 .. $#vals) { $hash{$names[$i]} = $vals[$i]; } push @data, \%hash; } print Dumper(\@data); __END__ $VAR1 = [ { 'first' => '10', 'opens' => '1', 'min' => '0', 'inc' => '0', 'max' => '0', 'last' => '100', 'noise' => '0' }, { 'first' => '10', 'opens' => '2', 'min' => '3', 'inc' => '2', 'max' => '5', 'last' => '100', 'noise' => '1' }, { 'first' => '20', 'opens' => '3', 'min' => '3', 'inc' => '2', 'max' => '5', 'last' => '100', 'noise' => '0' } ];

    Update: I just saw jdporter's comment in the CB about "you have two elements in the hash named 'inc'. You can only have one."

      my @data; for my $set (split /#/, $patterns) { my @vals = split /\s+/, $set; my %hash; for my $i (0 .. $#vals) { $hash{$names[$i]} = $vals[$i]; } push @data, \%hash; }
      my @data; for ( split /#/, $patterns ) { my %hash; @hash{ @names } = split; push @data, \%hash; }

        Dang. Can you really do that?

        Accessing a hash with the array op like that? ANd how do you garantee they map value to key?

        I bow to your perliness.

        my $h = {}; my @data = map {{%{@$h{@names} = split, $h}}} split '#', $patterns;