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

I have a below code:
#!/usr/bin/perl -w use strict; use warnings; my @data_list = ( {key => 'date', value => ''}, {key => 'correct', value => 'Article_text1'}, {key => 'correct', value => 'Article_text2'}, {key => 'date', value => '2009-01-01'}, {key => 'date', value => '2009-01-02'}, {key => 'date', value => ''} ); my ($correction, $date); foreach my $data_pair(@data_list) { $correction = $data_pair->{value} if exists $data_pair->{value} and # could be undef defined $data_pair->{value} and # at least "" length $data_pair->{value} and # has length $data_pair->{value} and # has true value $data_pair->{key} eq 'correct'; $date = $data_pair->{value} if exists $data_pair->{value} and # could be undef defined $data_pair->{value} and # at least "" length $data_pair->{value} and # has length $data_pair->{value} and # has true value $data_pair->{key} eq 'date'; if($correction && $date) { my $sql .= " INSERT IGNORE INTO table SET text = '".$correction."', date='".$date."'"; print $sql; # Reset for the next loop ($correction, $date) = (undef, undef); } }
The output is as below which is not correct
INSERT IGNORE INTO table SET text = 'Article_text2', date='2009-01-01'
Instead the output should be
INSERT IGNORE INTO table SET text = 'Article_text1', date='2009-01-01' INSERT IGNORE INTO table SET text = 'Article_text2', date='2009-01-02'
The keys and values are always passed in the order as above in the array @data_list How to match the first the text and first date and get the required output.

Replies are listed 'Best First'.
Re: Alternative values from array and print
by moritz (Cardinal) on Jul 16, 2009 at 07:08 UTC
    Using a proper hash greatly simplifies this task (as you have been told many times already).
    use strict; use warnings; use List::Util qw(first); my %data = ( date => ['', '2009-01-01', '2009-01-02', ''], correct => ['Article_text1', 'Article_text2'], ); my $correction = first { length($_) } @{$data{correct}}; my $date = first { length($_) } @{$data{date}};

    Please read perldsc and perlreftut which both explain data structures in Perl very nicely.

    (Update: change link from perlref to perlreftut, which is more introductory).

      The data is stored in the way as in @data_list. How to convert to hash only for key correct and date. When I print print " $correction : $date\n"; Only first pair of value is printed
        By iterating over your current data structure and building the desired one. Read the tutorials I pointed you to, they really help.
        Only first pair of value is printed

        Right, that's how I understood your requirements. If that's not what you want, you might try to formulate a bit clearer what you want.

      The data is stored in the way as in @data_list. How to convert to hash only for key correct and date.
Re: Alternative values from array and print
by Jenda (Abbot) on Jul 16, 2009 at 09:43 UTC

    The code does exactly what you wrote. Let's see ... the first iteration of the loop leaves both variables unset and nothing's printed. The second sets $correction, but the $date is empty so nothing is printed. The third resets $correction to 'Article_text2', but $date is still empty so no print either. The fourth finally sets the $date and prints and clears both variables. The fifth sets $date, but the $correction is empty and nothing is printed. And the last one doesn't do a thing.

    If you want to match the first with the first, second with second ... no matter about the order in which the dates and corrections are mixed together you have to be ready to remember more dates and corrections, not just the last one. Either first loop through your array and build an array of @dates and array of @corrections and then loop through both those arrays at once and print the statements or loop through your array, push() the encountered dates and corrections into arrays and whenever both arrays have elements, shift() the first element from both and print the statement.

    Jenda
    Enoch was right!
    Enjoy the last years of Rome.