微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

提取数组中相似数据的快速方法

如何解决提取数组中相似数据的快速方法

| 我不完全知道如何在下面的问题中陈述我的问题,请耐心等待。 问题: 我有一个多维数组,如下所示:
$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\',\'300\']
$raw_list[2][\'123\',\'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的新手,不知道如何最好地解决此问题。     

解决方法

一千个索引不是很多...是什么让您认为您的代码很慢?哪一部分很慢? 如果第一个元素是如此重要,则可以首先重新排列数据结构以使其索引:
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\',\'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\'
    }
}
实际上,您将所有这些都封装在一个对象中。     ,如果我对您的理解正确,那么您想获取第二维的第一个值中具有相同值的记录(示例中为
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\';
}
    ,您可以将数据放入由第一个元素索引的哈希中,然后快速遍历哈希的每个元素:
#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\";
}
当然,此解决方案仅在您需要处理每个组并希望分别进行处理时才有意义,并且可能需要进行多次通过。     ,
map($keys{$_->[0]} = 1,@raw_list);
foreach $k (keys %keys)
{
 @a = grep($_->[0]==$k,@raw_list);
 # do something with @a;
}
    

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。