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

I have an array of arrays (sorted one), and I am looking in for a way to slice the elements based on a particular column values. An Example might help,
@arr = ([12, "abc", 30], [24, "abc", 30], [26, "abc", 30], [14, "abc", 40], [46, "abc", 40], [2, "abc", 50]); #I want to slice them based on column 3, such that @arr1 = ([12, "abc", 30], [24, "abc", 30], [26, "abc", 30]); @arr2 = ([14, "abc", 40], [46, "abc", 40]); @arr3 = ([2, "abc", 50]);
And yes, the values in column 3 aren't fixed one. They can be any number, and I want to group arrays based on its value.

Any help will be appreciated.

Replies are listed 'Best First'.
Re: slicing array based on values but not index
by Bloodnok (Vicar) on Aug 13, 2009 at 21:14 UTC
    You mean something like:
    use warnings; use strict; use Data::Dumper; my @arr = ( [12, "abc", 30], [24, "abc", 30], [26, "abc", 30], [14, "abc", 40], [46, "abc", 40], [2, "abc", 50] ); my %res; map { push @{$res{$_->[2]}}, $_ } @arr; warn Dumper values %res;
    Giving:
    $ perl tst.pl $VAR1 = [ [ 2, 'abc', 50 ] ]; $VAR2 = [ [ 14, 'abc', 40 ], [ 46, 'abc', 40 ] ]; $VAR3 = [ [ 12, 'abc', 30 ], [ 24, 'abc', 30 ], [ 26, 'abc', 30 ] ];
    A user level that continues to overstate my experience :-))
      Kudos!!!

      Please excuse my poor knowledge, can you explain how is it working?
        map { push @{$res{$_->[2]}}, $_ } @arr;
        map loops thro' all values of the array @arr - setting $_ to each value (an array ref.) in turn - pushing that value onto an array in a hash keyed on the last element of each individual array.

        As you can see, the result you're interested in is the array of values of the newly created hash.

        A user level that continues to overstate my experience :-))
Re: slicing array based on values but not index
by bichonfrise74 (Vicar) on Aug 13, 2009 at 22:34 UTC
    If you want to really pursue the answer of ssandv, you can try something below.
    As you can see, it is not as nice and efficient as the one given by Bloodnok.
    #!/usr/bin/perl use strict; use Data::Dumper; my %record; my %third_col; my @arr = ( [12, "abc", 30], [24, "abc", 30], [26, "abc", 30], [14, "abc", 40], [46, "abc", 40], [2, "abc", 50] ); $third_col{ $_->[2] }++ for (@arr); for my $i (@arr) { push ( @{ $record{$i->[2]} }, $i ) if ( grep /$i->[2]/, keys %third_col ); } print Dumper \%record;
Re: slicing array based on values but not index
by ssandv (Hermit) on Aug 13, 2009 at 21:26 UTC
    my @arr1 = grep {$_->[2]==30} @arr; is one way of accomplishing something like this.
      but that will not give remaining output where $_->2==40 or 50. And this requires to know all the values column3 can have.
        grep is mighty helpful.

        If you can't figure out how to get all the values column 3 has, you have bigger issues, since this clearly shows how to get the value in column 3. Perlmonks isn't here to do your work for you. You need to put some of your own effort in.