Arrays 在Perl中,如何将长度未知的文件读入多个散列以存储在数组中供以后使用?
我有一个配置文件,看起来有点像这样:Arrays 在Perl中,如何将长度未知的文件读入多个散列以存储在数组中供以后使用?,arrays,perl,hash,Arrays,Perl,Hash,我有一个配置文件,看起来有点像这样: add 1 2 concatenate foo bar blat my %temphash = (name=>'add', args=>[1,2]); push (@array, \%temphash); 我要做的是将其转换为散列,如%hash=(name=>“add”,args=>[1,2])等,并将散列引用推送到单个数组中。在文件中循环并创建每个散列似乎足够简单,除非在命名这些散列以将它们的引
add
1
2
concatenate
foo
bar
blat
my %temphash = (name=>'add', args=>[1,2]);
push (@array, \%temphash);
我要做的是将其转换为散列,如%hash=(name=>“add”,args=>[1,2])
等,并将散列引用推送到单个数组中。在文件中循环并创建每个散列似乎足够简单,除非在命名这些散列以将它们的引用推送到数组中时我遇到了困难。配置文件将一直更改,并且要存储不同数量的名称/参数组合。有没有一种方法可以遍历散列名,这样我就可以一次一个地将它们放入数组中
目前看来是这样的:
add
1
2
concatenate
foo
bar
blat
my %temphash = (name=>'add', args=>[1,2]);
push (@array, \%temphash);
我是否可以将该%temphash
转换为动态生成的内容,并在转到下一个之前将其推送
编辑:上下文
计划是使用这些“名称”键来调用子例程。所以像这样的东西可以起作用:
my %subhash = (add=>\&addNumbers, concatenate=>\&concat);
除了我需要调用的子程序列表在配置文件中之外,我不知道它们是什么,直到我开始阅读它。即使我在配置文件中包含了子例程的名称,我如何遍历它们并将它们作为元素添加到该散列中?如果我正确理解了您的要求,那么您可以编写:
push @array, { name=>'add', args=>[1,2] };
其中,{…}
是对匿名哈希的引用
也就是说,我有点惊讶于您需要一个哈希数组,而每个哈希只有一个名称
和args
。为什么不使用从名称到参数的单个哈希映射
%array = ( add => [ 1, 2 ], concatenate => [ 'foo', 'bar', 'baz' ] );
如果我正确理解了你的要求,那么你可以写:
push @array, { name=>'add', args=>[1,2] };
其中,{…}
是对匿名哈希的引用
也就是说,我有点惊讶于您需要一个哈希数组,而每个哈希只有一个名称
和args
。为什么不使用从名称到参数的单个哈希映射
%array = ( add => [ 1, 2 ], concatenate => [ 'foo', 'bar', 'baz' ] );
好的,您可以简单地使用花括号创建匿名哈希:
push @array, { name => 'add', args => [1,2] };
您可以通过使用my
声明的词法范围来创建相同的效果。例如:
my @array;
while ( ... ) {
...
my %hash = ( ... );
push @array, \%hash;
}
好的,您可以简单地使用花括号创建匿名哈希:
push @array, { name => 'add', args => [1,2] };
您可以通过使用my
声明的词法范围来创建相同的效果。例如:
my @array;
while ( ... ) {
...
my %hash = ( ... );
push @array, \%hash;
}
像这样的东西可以满足你的需要
use strict;
use warnings;
open my $fh, '<', 'data_file' or die $!;
my $item;
my @data;
while (<$fh>) {
chomp;
next unless /^(\s*)(.+?)\s*$/;
if ($1) {
push @{ $item->{args} }, $2;
}
else {
push @data, $item if $item;
$item = { name => $2, args => [] };
}
}
push @data, $item if $item;
use Data::Dump;
dd \@data;
像这样的东西可以满足你的需要
use strict;
use warnings;
open my $fh, '<', 'data_file' or die $!;
my $item;
my @data;
while (<$fh>) {
chomp;
next unless /^(\s*)(.+?)\s*$/;
if ($1) {
push @{ $item->{args} }, $2;
}
else {
push @data, $item if $item;
$item = { name => $2, args => [] };
}
}
push @data, $item if $item;
use Data::Dump;
dd \@data;
我有点困惑。也许您正在寻找
$temphash{$key}=>[1,2]
where$key='add'
我有点困惑。也许您正在寻找$temphash{$key}=>[1,2]
where$key='add'
对动态文件使用单个哈希可能会覆盖出现在不同位置的相同键。对动态文件使用单个哈希可能会覆盖出现在不同位置的相同键。新手问题:如果%hash的作用域仅限于该循环,我仍然可以遍历该数组中的元素吗在别处我从来没有做过匿名散列。听起来有颠覆性。数据将保存在数组中,引用仍将指向内存中的同一地址。但是,名称空间引用(例如,%hash
)将被销毁。匿名散列/数组是解决这些“一次性变量”情况的非常好的方法。好的,还有一个问题需要解决。我使用这个数组来执行类似的操作:foreach(@array){print“Yo\n”;}
但它最终会为存储的每个哈希值(名称和参数)运行该块一次,而不是为每个哈希运行一次。这与散列是匿名的有关吗,还是我缺少了一些更基本的内容?新手问题:如果%hash只作用于该循环,我还能在其他地方迭代该数组中的元素吗?我从来没有做过匿名散列。听起来有颠覆性。数据将保存在数组中,引用仍将指向内存中的同一地址。但是,名称空间引用(例如,%hash
)将被销毁。匿名散列/数组是解决这些“一次性变量”情况的非常好的方法。好的,还有一个问题需要解决。我使用这个数组来执行类似的操作:foreach(@array){print“Yo\n”;}
但它最终会为存储的每个哈希值(名称和参数)运行该块一次,而不是为每个哈希运行一次。这和散列的匿名性有什么关系吗?还是我缺少了一些更基本的东西?