in reply to Sort multidimensional array by third item

Whoops.

OK, so DataDumper revealed that my script is in fact producing an array full of empty references and I've evidently confused myself more than I thought...consequently I have a new question.

I have a file that looks like this:

7 1 2 20 2 3 15 3 4 3 4 5 17 5 6 28 6 1 23 1 7 1 2 7 4 3 7 9 4 7 16 5 7 25 6 7 36 -1

What I would like to do is take all the lines that are not the first or last line and make a sortable multidimensional array out of them, as described above.

My current code is:

#!/usr/bin/perl use warnings; use strict; use Data::Dumper; #open initial file open FILE, "graph.txt" or die "Error with original file: $!"; #open empty file to write to #open NEWFILE, ">output.txt" or die "Error with output file: $!"; #Get array with lines of file my @line_array = <FILE>; #reduce array to content info only shift(@line_array); pop(@line_array); #initialize item array and something to hold it during loop our @item_array; our @hold_array; #convert each edge string to an array, push it onto item_array for (my $i = 0; $i < scalar(@line_array); $i++) { our $line = $line_array[$i]; @hold_array = split(/\s/, $line); push(@item_array, \@hold_array); } print Dumper @item_array;

This produces in Dumper:

$VAR1 = [ '6', '7', '36' ]; $VAR2 = $VAR1; $VAR3 = $VAR1; $VAR4 = $VAR1; $VAR5 = $VAR1; $VAR6 = $VAR1; $VAR7 = $VAR1; $VAR8 = $VAR1; $VAR9 = $VAR1; $VAR10 = $VAR1; $VAR11 = $VAR1; $VAR12 = $VAR1;

Pretty sure this isn't what I want...am I approaching this the wrong way?

Thank you both for your help, by the way...you're awesome! =)

Replies are listed 'Best First'.
Re^2: Sort multidimensional array by third item
by kennethk (Abbot) on Nov 12, 2010 at 20:48 UTC
    Since @hold_array is outside the scope of your for loop, you are repeatedly pushing a reference to the same array to the end of your @item_array. An easier way to achieve your goal would be using anonymous arrays - see Making References in perlreftut. This might look like:

    for my $line (@line_array) { push(@item_array, [split(/\s/, $line)]); }

    If you want to use an explicit temporary storage array, you could use a variable that is scoped to the loop using my. This way, each iteration will create a new array with the same name, so each reference will be different.

    for my $line (@line_array) { my @hold_array = split(/\s/, $line); push(@item_array, \@hold_array); }

    Note I've swapped to Foreach Loops syntax to avoid possible indexing errors.

    I also note you use our a lot. Each time you do that, you are creating a global variable. Is there some reason you want to do that? Likely, you should be using my instead.

Re^2: Sort multidimensional array by third item
by Tux (Canon) on Nov 12, 2010 at 20:37 UTC

    Why not be a little more flexible and defensive ...

    my @unsorted; while (<FILE>) { my @fields = m/([0-9]+)/g; @fields == 3 and push @unsorted, \@fields; } my @sorted = sort { $a->[2] <=> $b->[2] } @unsorted;

    Enjoy, Have FUN! H.Merijn