Arrays 一次处理perl数组
我有一个包含许多条目的数组,如:Arrays 一次处理perl数组,arrays,perl,hash,hashmap,Arrays,Perl,Hash,Hashmap,我有一个包含许多条目的数组,如: "a->b->c->x->n" "something->something1->somethingelse" 我想一次从数组中提取所有奇数元素,并用它们的唯一值进行散列,如: %s = { "b" => '1' #the values don't matter too much, they could be # occurences, I am going to use keys %s. "x" =&g
"a->b->c->x->n"
"something->something1->somethingelse"
我想一次从数组中提取所有奇数元素,并用它们的唯一值进行散列,如:
%s = {
"b" => '1'
#the values don't matter too much, they could be # occurences, I am going to use keys %s.
"x" => '1'
"something1" => '1'
}
目前,我正在分几个步骤来完成这项工作,但只是在阵列中循环需要花费大量的时间,因此我认为有一些方法可以做得更好
my ( @odds, @evens );
foreach (@arr) {
my $i = 0;
push @{ $i++ % 2 ? \@odds : \@evens }, $_ for split /->/, $_;
}
%s = map { $_ => '1'; } @odds;
有没有建议一次处理整个阵列?您的请求毫无意义。如果要对数组的每个元素执行某些操作,则必须循环遍历数组的每个元素(无论是否使用
for
)
我在代码中没有看到任何慢的东西(除非操作系统因为内存不足而开始使用虚拟内存)。填充@evens
而从不使用它是一种浪费
以下是代码的更清晰版本。它也更快(多亏了pairvalues
和避免临时存储),但实际上不应该如此
use List::Util qw( pairvalues ); # 1.29+
my %s;
for (@arr) {
++$s{$_} for pairvalues split /->/;
}
如果您不介意奇怪/丑陋的代码,那么下面的代码甚至更快(如果只是稍微快一点):
你的要求毫无意义。如果要对数组的每个元素执行某些操作,则必须循环遍历数组的每个元素(无论是否使用
for
)
我在代码中没有看到任何慢的东西(除非操作系统因为内存不足而开始使用虚拟内存)。填充@evens
而从不使用它是一种浪费
以下是代码的更清晰版本。它也更快(多亏了pairvalues
和避免临时存储),但实际上不应该如此
use List::Util qw( pairvalues ); # 1.29+
my %s;
for (@arr) {
++$s{$_} for pairvalues split /->/;
}
如果您不介意奇怪/丑陋的代码,那么下面的代码甚至更快(如果只是稍微快一点):
如果您只对列表中那些具有奇数索引的元素感兴趣,那么C风格的
for
循环显然是一个选择
use strict;
use warnings 'all';
my @arr = ( "a->b->c->x->n", "something->something1->somethingelse" );
my %s;
for ( @arr ) {
my @k = split /->/;
for ( my $i = 1; $i < @k; $i += 2 ) {
$s{ $k[$i] } = 1;
}
}
use Data::Dumper;
print Dumper \%s;
您可能还想考虑一个正则表达式解决方案,如果<>代码> -> /COD>之间的值确实符合您的描述。这假定列表始终包含奇数个字符
for ( @arr ) {
$s{ $1 } = 1 while /->(\w+)->/g;
}
此循环的结果与前面代码的结果相同如果您只对列表中具有奇数索引的元素感兴趣,那么C样式的
for
循环是明显的选择
use strict;
use warnings 'all';
my @arr = ( "a->b->c->x->n", "something->something1->somethingelse" );
my %s;
for ( @arr ) {
my @k = split /->/;
for ( my $i = 1; $i < @k; $i += 2 ) {
$s{ $k[$i] } = 1;
}
}
use Data::Dumper;
print Dumper \%s;
您可能还想考虑一个正则表达式解决方案,如果<>代码> -> /COD>之间的值确实符合您的描述。这假定列表始终包含奇数个字符
for ( @arr ) {
$s{ $1 } = 1 while /->(\w+)->/g;
}
这个循环的结果与前面代码的结果相同@ikegami:我见过perl代码,其中一次处理整个数组,例如使用grep或map。我认为这可能比在每个条目中循环要快。你错了
grep
和map
的循环数与for
的循环数一样多,将结果标量分配给数组的赋值会在所有标量上均匀循环。注意。1) 对我的$i(0..$#arr)使用
2)只收集赔率///否则,您必须访问每个元素,并且必须访问每个(第二)子字符串。(但是尝试只访问每一秒的子字符串需要函数调用,而且速度会慢一些。)Re“grep
和map
与for
”的循环一样多,实际上,for(@a)BLOCK
比map BLOCK@a
和grep BLOCK@a
效率更高,因为它经过优化,可以迭代@a
的索引,而map
和grep
将@a
的所有元素放在堆栈上。@ikegami:我见过一个perl代码,其中一次处理整个数组,例如,使用grep或map。我认为这可能比在每个条目中循环要快。你错了grep
和map
的循环数与for
的循环数一样多,将结果标量分配给数组的赋值会在所有标量上均匀循环。注意。1) 对我的$i(0..$#arr)使用
2)只收集赔率///否则,您必须访问每个元素,并且必须访问每个(第二)子字符串。(但是尝试只访问每一秒的子字符串需要函数调用,而且速度会慢一些。)Re“grep
和map
与for
”的循环一样多,实际上,for(@a)BLOCK
比map BLOCK@a
和grep BLOCK@a
更有效,因为它经过优化,可以迭代@a
的索引,而map
和grep
将@a
的所有元素放在堆栈上。