3

我想用下面显示的数据按 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循环中工作?

4

3 回答 3

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;
}
于 2014-09-15T04:06:00.757 回答
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'
        }
    ]
};
于 2014-09-15T03:39:24.587 回答
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。)

于 2014-09-15T03:41:57.810 回答