in reply to Re: Re: Printing out multiple array lists and more!
in thread Printing out multiple array lists and more!

Well, I'm not sure how you got the next if... line to work. On my machine (Perl 5.6.0), it seems to get executed as:

next if( $c == 0 and $c++ );

That is, the next never gets executed because it's basically saying if( $c == 0 and $c != 0 ). Frankly, I expected it to execute the next/if part first and short-cut the ++ so that it went into an infinite loop. Regardless, it seems like a very odd piece of code that is not consistant between systems. *shrug*

My point about "$_ |" was that you added the trailing pipe character to the third file's values (ie, the third column) so you probably would've ended up with something more like: "var | var | var |" instead.

Answer to Question 1: my $header = <$file>; does, in fact, strip off the header line. It does this by, basically, reading in the first line of the file. You obviously are familiar with the diamond operator for reading from a file. It just reads in a single line of the file (when called in scalar context) and returns it. There's special magic when it's used as the condition of a while loop (as in your code, and later in mine) that it automagically stores the returned line in $_. But that's just special. Here, we're just manually storing the returned line into $header.

The purpose of localizing $_ is so that, if the code is called by someone who happens to be using $_ (such as within a foreach or while loop), we don't go and clobber their value in it. You should almost always do this whenever you use global built-ins in a subroutine like this (unless you're using $_ as the default iterator for a for(?:each)? loop, since for loops automatically localize $_ for ya). It's just good practice.

The $var->[$index] notation means that $var is not actually an array but, rather, a reference to an array (kinda like a pointer in C but safer). You have to use the -> notation to dereference $var so that perl knows you mean to use $var instead of @var. You could also use the curly-brace form: ${$var}[$index] which means the same thing. Luckily, it looks like we won't have to worry about this anymore once Perl 6 comes around. I'm definately looking forward to that. ;-) Auto-vivification is where Perl tries to DWYM when you use an undefined value as an array (or hash) reference. Basically, it creates the anonymous array for you.

As for unless(@{$listref->[$c]} and $_ != $listref->[$c][0])... Think of $listref as a two dimensional array, with $c as the row and the second index (0, in this case) as the column. So, the $_ != $listref->[$c][0] basically compares the current value ($_) to the value in the first column of the $c'th row. If there are no columns in the current row (ie, @{$listref->[$c]} == 0, or is false), or if the current value is equal to the value in the first column of that row, the push adds another column to the row containing the current value. Otherwise, the other push adds a blank value to that column.

For more information on array references and multidimensional arrays, check out `perldoc perlreftut` and perlref.

You're getting the undefined value warnings because second file has less lines in it than the other two files. I didn't put in any checks anywhere to account for files of differing lengths.

As for the values not getting printed in the second column, that's because the values in file 2 don't match the values in file 1 or 3. Perhaps there was a misunderstanding of the goal. I understood you to mean that you wanted to compare the files on a line-by-line basis, comparing the lines in the file and printing the ones that were equal. Such that the following files (ignoring header lines):

File 1 File 2 File 3 5 1 5 6 2 6 7 5 7 8 6 8

Would, in fact, produce the following output:

5 | | 5 6 | | 6 7 | | 7 8 | | 8

Perhaps you meant for it to actually compare the files on a value-by-value basis. Such that the same files as above would instead produce this output:

5 | 5 | 5 6 | 6 | 6 7 | | 7 8 | | 8

If you meant it to be the latter, let me know and I will try to come up with a solution for that. Perhaps I can even make it more understandable. ;-) Also, I'd like to know if the data is guaranteed to be numeric and, if so, what the range is. That would make the solution a bit easier.

Anyway, I'm glad to help. I'm sorry my code is so confusing. It's definately not the best I've ever written. :-P At any rate, HTH...

bbfu
Seasons don't fear The Reaper.
Nor do the wind, the sun, and the rain.
We can be like they are.