Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl-Sensitive Sunglasses
 
PerlMonks  

Iterate multiple arrays with added text

by Bman70 (Acolyte)
on May 23, 2017 at 19:44 UTC ( [id://1191014]=perlquestion: print w/replies, xml ) Need Help??

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

Hi, I'm looking at another ten hours of troubleshooting (sucks to not know much Perl!), so I thought I would ask. I have several arrays, @title, @author, @date, each of which have multiple elements. I need to output all the elements (several hundred) organized as:
Title: "title from array" Author: "author from array" Date: "Date from array"
In my searching the closest I got was another perlmonks thread:
while (@title, @author, @date) { print join ': ', map shift @$_ // 'NULL', \@title, \@author, \@dat +e; print "\n"; }
This gets all the information out, but not formatted right. Would I be able to add the text and newlines to this code, or should I use something entirely different? I realize it could probably be done with hashes but currently it's in arrays so hoping that can work. Thanks!

Replies are listed 'Best First'.
Re: Iterate multiple arrays with added text
by haukex (Archbishop) on May 23, 2017 at 19:50 UTC

    How do I Loop over multiple arrays simultaneously ? - although it sounds very much like it'd be better if you structured your data as an "array of hashes".

    Update: As for the part of your question about formatting, it's probably easier if you split the problem into two: first get the current values into scalars (e.g. my ($title, $author, $date) = ...), and then output them with one or more print or printf statements.

      Update: I did get it to work using this code:
      foreach my $i (0 .. @titles) { print "Title: $title[$i]\n"; print "Author: $author[$i]\n"; print "Date: $date[$i]\n\n"; }
      However, while it outputs what I need, it gives the error:
      Use of uninitialized value within @titles in concatenation (.) or stri +ng at bdb.pl line 51. Title: Use of uninitialized value within @authors in concatenation (.) or str +ing at bdb.pl line 52. Author: Use of uninitialized value within @date in concatenation (.) or string + at bdb.pl line 53. Date:
      So when I'm using  print "Title: $title[$i]\n";, that $title is triggering the error.

        It's actually all three generating the warning.

        What you need is:

        for my $i (0 .. $#titles){ ... }

        Note the $#titles as opposed to @titles. You're essentially causing an off-by-one issue by using the array count as opposed to the element position (index). Example:

        perl -wMstrict -E 'my @x=(qw(a b c)); say "$_: $x[$_]" for (0..@x)' 0: a 1: b 2: c Use of uninitialized value in concatenation (.) or string at -e line 1 +. 3:

        vs:

        perl -wMstrict -E 'my @x=(qw(a b c)); say "$_: $x[$_]" for (0..$#x)' 0: a 1: b 2: c

        Hi, @titles in scalar context returns the number of elements in the array. But the index of the last element is one less than that.

        To loop through the indices of your array, use $#titles instead, which will give the index of the last element.

        for my $i ( 0 .. $#titles ) { ... }

        Hope this helps!


        The way forward always starts with a minimal test.

        You've added some vars -- @thumbs and @schedpubs Deus ex machina EXCEPT that the 'god out of a machine' reference is to a theatrical/scripting device that solves the author's problem by injecting an un-foreshadowed solution (Superman -- never mentioned before -- arrives to save the damsel in distress; Dr. X -- the protagonist -- without any prior lab experience shown comes up with the magic potion to keep the sub shining; etc.) Here, the arrays certainly unforeshadowed, but lacking our psi powers (only temporarily, I assure you) we are (well, I am) at a loss for anything more helpful than a WAG.

        That WAG is that your data is inconsistent;, ie, doesn't have all the fields in each record (something you're banking on with the script you showed us [HINT, Hint: show all your relevant code, but pared down to the smallest example that illustrates your problem].

        If that's any serious chance that my WAG is on target, you'll do well to read about ways to test for the existance of data you're importing/processing and about transforming missing data to something that won't choke your program when your input (or lack thereof in this case) makes a variable "uninitialized"(the ternary operator for an off the top of my head notion).

Re: Iterate multiple arrays with added text
by james28909 (Deacon) on May 23, 2017 at 22:03 UTC
    Have you thought about using hashes? Wouldn't it be a little easier to manage? I once was very confused by them, and I still am depending on how complex the data is, but I know enough to get what I need done... done. I'll leave this here for you to examine :)
    use strict; use warnings; use Data::Dumper; # $Data::Dumper::Terse = 1; my %library; #this is where we store title, author, date my $i = 1; #iterator for hash key name while (<DATA>) { my ( $title, $author, $date ) = split /\|/, $_; # the '|' just sep +erates records chomp($date); #because date has newline read from my example push @{ $library{ $i++ } }, $title, $author, $date; #put it in the + hash of arrays '%library' } foreach my $key ( sort { $a <=> $b } keys %library ) { #sort isnt nece +ssary but i put it there to give you an example print "Book #$key\n"; print "Title: @{$library{$key}}[0]\n"; print "Author: @{$library{$key}}[1]\n"; print "Date: @{$library{$key}}[2]\n\n"; } # use Data::Dumper to quickly verify data; # print Dumper %library; __DATA__ Beginning Perl|Simon Cozens|May 25, 2000 Modern Perl|Chromatic|2012 Impatient Perl|Greg London|Feb 7, 2004 Extreme Perl|Robert Nagler|2004 Embedding Perl in HTML with Mason|Dave Rolsky, Ken Williams|Oct 2002
    If you want to try out this code, click the download link below and copy/paste.
    Have fun learning!

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://1191014]
Approved by haukex
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others romping around the Monastery: (4)
As of 2024-04-18 23:24 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found