perl组使用fetchrow_hashref生成散列

时间:2014-09-15 03:20:54

标签: arrays perl hash multidimensional-array hashref

我想按countryid对结果进行分组,数据如下所示。

my @test = ();
my $st   = qq[
    SELECT id,countryID,abbrev
    FROM myTable
];
my $q = $data->prepare($st);
$q->execute() or query_error($st);
while ( my $result = $q->fetchrow_hashref ) {
    push @test, $result;
}

使用fetchrow_hashref我没有问题取消结果

use Data::Dumper;
print STDERR Dumper(\@test);

返回

$VAR1 = [
    {   'id'        => '1',
        'countryID' => '1',
        'title'     => 'Title 1',
        'abbrev'    => 't1'
    },
    {   'id'        => '2',
        'countryID' => '2',
        'title'     => 'Title 2',
        'abbrev'    => 't2'
    },
    {   'id'        => '3',
        'countryID' => '3',
        'title'     => 'Title 3',
        'abbrev'    => 't3'
    },
    {   'id'        => '4',
        'countryID' => '1',
        'title'     => 'Title 4',
        'abbrev'    => 't4'
    }
];

我想按国家/地区对其进行分组,如下所示。

$VAR1 = [
    'countries' => {
        '1' => [
            {   'id'     => '1',
                'title'  => 'Title 1',
                'abbrev' => 't1'
            },
            {   'id'     => '4',
                'title'  => 'Title 4',
                'abbrev' => 't4'
            }
        ],
        '2' => [
            {   'id'     => '2',
                'title'  => 'Title 2',
                'abbrev' => 't2'
            }
        ],
        '3' => [
            {   'id'     => '3',
                'title'  => 'Title 3',
                'abbrev' => 't3'
            }
        ]
    }
];

如何在while循环中使用它?

3 个答案:

答案 0 :(得分:2)

忽略示例数据结构中的错误,您基本上希望将哈希的表单数组转换为哈希数组哈希的哈希值。完成初始数据结构设置后,可以执行以下操作来创建新的嵌套数据结构:

for my $href ( @test ) {
    my $id = $href->{countryID};
    delete $href->{countryID};
    push @{ $test2->{countries}{$id} }, $href;
}

迭代数组@test的每个元素,它基本上是一个哈希引用数组。创建一个变量$id,它将从散列中捕获countryID值。我们从哈希引用中删除它,然后将该哈希引用分配给我们的新嵌套数据结构,其中countries作为第一级key$id作为第二级键。

我们使用push语法来创建此类引用的数组。

注意:正如评论中thb所述,这会破坏原始数据结构。如果您想保留原始结构,请将代码修改为以下内容:

for my $href ( @test ) {
    my $copy = { %$href };
    my $id   = $copy->{countryID};
    delete $copy->{countryID};
    push @{ $test2->{countries}{$id} }, $copy;
}

答案 1 :(得分:1)

像这样的东西,输入/输出数据结构可能不是你拥有或想要的,你可以修补它。

use strict;
use Data::Dumper;

$a = [
    {   'id'        => '1',
        'countryID' => '1',
        'title'     => 'Title 1',
        'abbrev'    => 't1'
    },
    {   'id'        => '2',
        'countryID' => '2',
        'title'     => 'Title 2',
        'abbrev'    => 't2'
    },
    {   'id'        => '3',
        'countryID' => '3',
        'title'     => 'Title 3',
        'abbrev'    => 't3'
    },
    {   'id'        => '4',
        'countryID' => '1',
        'title'     => 'Title 4',
        'abbrev'    => 't4'
    }
];

my $b = {};

for my $item (@$a) {
    if ( exists( $b->{ $item->{'countryID'} } ) ) {
        push( @{ $b->{ $item->{'countryID'} } }, $item );
    } else {
        $b->{ $item->{'countryID'} } = [$item];
    }
}
print Dumper($b);

以上版画:

$VAR1 = {
    '1' => [
        {   'abbrev'    => 't1',
            'title'     => 'Title 1',
            'id'        => '1',
            'countryID' => '1'
        },
        {   'abbrev'    => 't4',
            'title'     => 'Title 4',
            'id'        => '4',
            'countryID' => '1'
        }
    ],
    '3' => [
        {   'abbrev'    => 't3',
            'title'     => 'Title 3',
            'id'        => '3',
            'countryID' => '3'
        }
    ],
    '2' => [
        {   'abbrev'    => 't2',
            'title'     => 'Title 2',
            'id'        => '2',
            'countryID' => '2'
        }
    ]
};

答案 2 :(得分:1)

你需要稍微修改一下你的语法(例如=>而不是= >),但是一旦你这样做了,这样的事情应该很好用。

for (@$VAR1_orig) {
    my %a = %$_;
    my $countryID = $a{countryID};
    delete $a{countryID};
    push @{$VAR1->{countries}{$countryID}}, \%a;
}

(顺便说一下,我已经在我的电脑上试过了。它有效。)

以上假设%$VAR1最初是空的,然后根据@$VAR1_orig填充它,之后您可以使用$VAR1做任何您喜欢的事情。 (我假设您知道Perl中%$@$的含义,但这可能不是初学者的话题,您可能知道。请参阅man 1 perlref