我不知道如何在一个问题中说明我的问题,所以请耐心等待。
问题:
我有一个多维数组,如下所示:
$raw_list[0]['123','foo','foo1','300']
$raw_list[1]['456','foo2','foo3','4']
$raw_list[2]['123','foo4','foo5','67']
$raw_list[3]['456','foo6','foo7','34']
这通常会非常大(可能会超过一千个索引?)
我想要做的是将所有记录与 $ raw_list [nth] [0] 中的相同第0个元素值分开,并对每个组进行操作,以便......
$raw_list[0]['123','foo','foo1','300']
$raw_list[2]['123','foo4','foo5','67']
然后我对这个小组进行操作以获得各种统计信息。例如,元素值“300”和“67”之和等等。
当前解决方案:
目前这就是我的代码实际上的样子。
my @anum_group = ();
@die_raw_list = sort {$a->[0] <=> $b->[0]} @die_raw_list;
my $anum_reference = @die_raw_list[0][0];
for my $row (0..$#die_raw_list)
{
if ($die_raw_list[$row][0] == $anum_reference)
{
push @anum_group, $die_raw_list[$row];
}
else
{
# Profile ANUM group
# ... operation to get statistical info on group here
# Initialize next ANUM group
$anum_reference = $die_raw_list[$row][0];
@anum_group = ();
push @anum_group, $die_raw_list[$row];
}
}
# Profile last ANUM group
# ... operation to get statistical info on group here
最后的想法和问题:
我意识到在非常大的数据上,这往往非常慢,我想加快速度。
我是Perl的新手,不知道如何最好地解决这个问题。
答案 0 :(得分:2)
一千个索引并不是那么多......是什么让你觉得你的代码很慢?什么部分很慢?
如果第一个元素很重要,您可以重新安排数据结构,以便首先将其编入索引:
my %raw_list = ('123' => [['foo', 'foo1', '300'],
['foo4', 'foo5', '67']],
'456' => [['foo2', 'foo3', '4'],
['foo6', 'foo7', '34']]);
你可以动态地构建它:
my %raw_list;
my $elt0 = '123';
my @rec = ('foo', 'foo1', '300');
push @{$raw_list{$elt0}}, \@rec;
并像这样处理:
foreach my $elt0 (keys %raw_list) {
my $records = $raw_list{$elt0};
foreach my $rec (@$records) {
# Now $elt0 is (e.g.) '123'
# and $rec->[0] is 'foo', $rec->[1] is 'foo1', $rec->[2] is '300'
}
}
要真的很干净,你可能希望将所有这些封装在一个对象中......
答案 1 :(得分:1)
如果我理解正确,您希望获取第二维中第一个值中相同值的记录,在示例中为123
,按其他字段对它们进行排序,然后比较内部的某些值它们。
这可以通过不同的值排序来完成:
my @sorted = sort {
$a->[0] <=> $b->[0] || # <=> for numerical
$a->[1] cmp $b->[1] || # cmp for non-numerical
$a->[2] cmp $b->[2] ...etc
} @die_raw_list;
然后,您只需循环浏览数据,选择所需的值即可。
如果您只想要一些值,可以使用以下简单的方法进行部分选择:
my @partial;
for my $refs (@die_raw_list) {
push @partial, $ref if $ref->[0] == '123';
}
答案 2 :(得分:1)
您可以将数据放入由第一个元素索引的哈希中,然后快速浏览哈希的每个元素:
#test data
my $foo = [[1,2,3],[1,5,6],[2,8,9]];
#group elements 1..n by first element
my %bar;
map { $bar{$_->[0]} ||= (); push(@{$bar{$_->[0]}},[@{$_}[1..@$_-1]]) } @$foo;
#lame dump
foreach (keys %bar) {
print "key: $_\n";
foreach (@{$bar{$_}}) {
foreach (@{$_}) {
print "$_ ";
}
print "\n";
}
print "\n";
}
当然,这个解决方案可能只有在您需要处理每个组时才有意义,并且希望单独进行,并且可能需要进行多次传递。
答案 3 :(得分:-2)
map($keys{$_->[0]} = 1, @raw_list);
foreach $k (keys %keys)
{
@a = grep($_->[0]==$k,@raw_list);
# do something with @a;
}