user1987607
user1987607

Reputation: 2157

perl create multiple arrays based on value and loop through them

I'm using perl to fetch data from a mysql database.

I store the 'SELECT' results in an array ($res):

$res = $sth->fetchall_arrayref;

I can loop through the array like this:

foreach $r1 (@{$res}) {
   print @{$r1}[0], ";", @{$r1}[1], ";", @{$r1}[2], "\n"; 
} 

Each $r1 has 3 elements, so this is an example of what would be printed after the foreach loop

1;100;A
2;105;C
3;100;G
4;500;A
5;200;B
6;650;B
7;204;A

I now want to do the following: Create subarrays based on the third element of each row.

So I want an array "A" that contains the rows where the third element equals A:

1;100;A
4;500;A
7;204;A

and so on for all possible third element values that occur multiple times. In this example this would lead to 2 arrays: 1 for "A" and 1 for "B". There would be no array for "C" and "G" because they only occur once as third element in the $res array.

I then want to loop through all the resulting arrays 1 by 1, row by row.

How can I achieve this in perl?

Upvotes: 1

Views: 180

Answers (1)

choroba
choroba

Reputation: 241868

The idiomatic way is to create a hash of arrays. The key will be the value of the third column, the value will be an anonymous array containing the values of columns 1 and 2.

You also need to postporocess the hash and remove the entries than only have a single value associated to the key.

#! /usr/bin/perl
use warnings;
use strict;
use feature qw{ say };

my $res = [
    [1, 100, 'A'],
    [2, 105, 'C'],
    [3, 100, 'G'],
    [4, 500, 'A'],
    [5, 200, 'B'],
    [6, 650, 'B'],
    [7, 204, 'A'],
];

my %by3rd;
for my $r1 (@$res) {
    push @{ $by3rd{ $r1->[2] } }, [ @$r1[0, 1] ];
}
for my $group (keys %by3rd) {
    delete $by3rd{$group} if 1 == @{ $by3rd{$group} };
}

use Data::Dumper; print Dumper \%by3rd;

Upvotes: 4

Related Questions