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

I have a bit of logic drain I hope I can explain what I am missing and what I want in a more coherent manner. Let me know if I have to add a bit more data or information. I have a excel sheet, which I am trying to load to a database. I have slurped the data in to a array of hashes. the data in the hash looks like this
( { col1 =>value1 col2 =>value2 col3=>value3|value4 col4=>value5|value6|value7 }, { col1 =>value8 col2 =>value9 col3=>value10|value11|value12 col4=>value13|value14|value15 } { col1 =>value16|value17 col2 =>value19|value18 col3=>value20 col4=>value21 } )
I have a piece of code that parses this data structure to get the value
foreach my $results (@$hash_of_excel){ for my $colname( sort keys %$results){ my @array = split /\|/,$results->{$colname}; foreach my $value (@array){ warn $results->{'col1'}, $results->{'col2'},$results->{'co +l3'}; last; } } last if $counter++ == 2; }
This would result me in the same value printing over n over for the number of columns present in each hash (ie 4 in our case). My question is how can I access different col for the DBI insert but without having to go through lot of for loops? And is there a way to check if the value has more than one values and pushing them to array instead of having to get all of them in an array? OR is this good to have the DBI inserts to a different sub routine and pass jus the required column values in an array? Please help. Thanks in advance.

Replies are listed 'Best First'.
Re: logical solution for a array of hash
by choroba (Cardinal) on Feb 12, 2015 at 22:50 UTC
    Crossposted at StackOverflow. Note that it's considered polite to inform about crossposting so that people not attending both sites don't waste time hacking a solution for a problem already solved at the other end of the Internet.
    لսႽ† ᥲᥒ⚪⟊Ⴙᘓᖇ Ꮅᘓᖇ⎱ Ⴙᥲ𝇋ƙᘓᖇ
Re: logical solution for a array of hash
by Perlbotics (Archbishop) on Feb 12, 2015 at 23:09 UTC

    Your question leaves room for interpretation ;-) My interpretation is, you want to put all combinations into a four column sized table. The following example unfolds the loops using a silly glob hack - don't do that for production code! There are modules on CPAN (e.g. iterator) to create multi-level for-loops.

    use strict; use warnings; my $hash_of_excel = [ { col1 => "value1", col2 => "value2", col3 => "value3|value4", col4 => "value5|value6|value7", }, { col1 => "value8", col2 => "value9", col3 => "value10|value11|value12", col4 => "value13|value14|value15", }, { col1 => "value16|value17", col2 => "value19|value18", col3 => "value20", col4 => "value21", } ]; foreach my $results (@$hash_of_excel){ my $glob_expression; for my $colname( sort keys %$results){ my @array = split /\|/,$results->{$colname}; $glob_expression .= '{' . join(',', @array) . '};'; } chop $glob_expression; print "EXP: $glob_expression:\n"; print "\t", join("\n\t", glob $glob_expression), "\n\n"; }

    Result:

    EXP: {value1};{value2};{value3,value4};{value5,value6,value7}: value1;value2;value3;value5 value1;value2;value3;value6 value1;value2;value3;value7 value1;value2;value4;value5 value1;value2;value4;value6 value1;value2;value4;value7 EXP: {value8};{value9};{value10,value11,value12};{value13,value14,valu +e15}: value8;value9;value10;value13 value8;value9;value10;value14 value8;value9;value10;value15 value8;value9;value11;value13 value8;value9;value11;value14 value8;value9;value11;value15 value8;value9;value12;value13 value8;value9;value12;value14 value8;value9;value12;value15 EXP: {value16,value17};{value19,value18};{value20};{value21}: value16;value19;value20;value21 value16;value18;value20;value21 value17;value19;value20;value21 value17;value18;value20;value21
    Did you asked for something like that?

Re: logical solution for a array of hash
by Anonymous Monk on Feb 12, 2015 at 22:53 UTC
    I don't understand what you want to do, does this help? Does it inspire a new question?
    #!/usr/bin/perl -- use strict; use warnings; use Data::Dump qw/ dd /; my $record = { col1 => "value8", col2 => "value9", col3 => "value10|value11|value12", col4 => "value13|value14|value15", }; dd( $record ); SomethingUnPipeModifyRecord( $record ); dd( $record ); dd( $record->{col4} ); dd( $record->{col4}[0] ); sub SomethingUnPipeModifyRecord { my( $rec ) = @_; for my $val( values %$rec ){ my $newval = [ split /\|/, $val ]; $val = $newval; } return $rec; } __END__ { col1 => "value8", col2 => "value9", col3 => "value10|value11|value12", col4 => "value13|value14|value15", } { col1 => ["value8"], col2 => ["value9"], col3 => ["value10", "value11", "value12"], col4 => ["value13", "value14", "value15"], } ["value13", "value14", "value15"] "value13"

      That's right but my question was how would I know whether the particular record has more than one values or not without looping through them?

      For example the col3 has more values but col2 has on value. I would like to skip the col2 from going through any loop if it has one value and proceed with the insert statements. If I have more than one values then I have to loop through them for each value to be inserted to the DB. Hope I am clearer this time.
Re: logical solution for a array of hash
by GotToBTru (Prior) on Feb 12, 2015 at 23:07 UTC

    I hope the Stackoverflow post is more coherent.

    So, in the end you want to

    insert into table (col1) values (value1) insert into table (col1) values (value8) insert into table (col2) values (value2) insert into table (col2) values (value9) insert into table (col3) values (value3) ... insert into table (col4) values (value14) insert into table (col4) values (value15)

    Is that correct? You want to retrieve the data from the array of hashes organized in such a way to facilitate that.

    Dum Spiro Spero
Re: logical solution for a array of hash
by martin (Friar) on Feb 12, 2015 at 23:00 UTC

    The loop variable of your inner loop is $value yet the loop body does not use that variable. Try replacing $results there by $value.

Re: logical solution for a array of hash
by shmem (Chancellor) on Feb 13, 2015 at 22:35 UTC

    update: This node should be reaped. I posted to the wrong thread... this is a reply to Re: Is is possible to use perl fork and ithreads within the same application

    The reason for wanting to mix the two is that I have to open up 300+ connections to unique devices.

    You don't tell what kind of connection that is, and what amount of code is involved interacting with those devices. Maybe you could make the connections into just (file)handles using pipe before forking, and IO::Select in the parent. If the creation and interaction with those devices is asynchronous (i.e. random wrt time), you could use an event based model using Event, EV or POE. That way your forked processes will be small enough, and will be returning claimed memory to the OS after execution. This is given with a lot of handwaving, of course; more of your code is required to give good advice.

    perl -le'print map{pack c,($-++?1:13)+ord}split//,ESEL'