首页 > 解决方案 > perl 根据值创建多个数组并循环遍历它们

问题描述

我正在使用 perl 从 mysql 数据库中获取数据。

我将“SELECT”结果存储在一个数组($res)中:

$res = $sth->fetchall_arrayref;

我可以像这样遍历数组:

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

每个 $r1 有 3 个元素,所以这是在 foreach 循环之后打印的示例

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

我现在想做以下事情: 根据每行的第三个元素创建子数组。

所以我想要一个数组“A”,其中包含第三个元素等于 A 的行:

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

对于多次出现的所有可能的第三个元素值,依此类推。在此示例中,这将导致 2 个数组:1 个用于“A”,1 个用于“B”。“C”和“G”将没有数组,因为它们只作为 $res 数组中的第三个元素出现一次。

然后,我想逐行逐行遍历所有生成的数组。

我怎样才能在 perl 中实现这一点?

标签: arraysperl

解决方案


惯用的方法是创建数组的散列。键将是第三列的值,值将是包含第 1 列和第 2 列值的匿名数组。

您还需要对哈希进行后处理并删除条目,而不是只有一个与键关联的值。

#! /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;

推荐阅读