我想根据用户输入动态创建数组。例如,如果用户将输入设为3,则应创建名为@message1
,@message2
和@message3
的三个数组。
我如何在Perl中完成?
答案 0 :(得分:16)
别。相反,使用数组数组:
my @message;
my $input = 3;
for my $index ( 0..$input-1 ) {
$message[$index][0] = "element 0";
$message[$index][1] = 42;
}
print "The second array has ", scalar( @{ $message[1] } ), " elements\n";
print "They are:\n";
for my $index ( 0..$#{ $message[1] } ) {
print "\t", $message[1][$index], "\n";
}
一些有用的规则位于http://perlmonks.org/?node=References+quick+reference
答案 1 :(得分:12)
我不得不问你为什么要这样做,因为这不是正确的方法。如果您有三个输入流,每个输入都需要存储为列表,则存储一个列表,这是一个列表列表(列表存储为数组引用):
my @input = (
[ 'data', 'from', 'first', 'user' ],
[ qw(data from second user) ],
[ qw(etc etc etc) ],
);
如果您的名称与每个用户的数据相关联,则可能需要使用该名称 作为哈希键,用于索引数据:
my %input = (
senthil => [ 'data', 'from', 'first', 'user' ],
ether => [ qw(data from second user) ],
apu => [ qw(etc etc etc) ],
);
有关详情,请参阅Perl Data Structures Cookbook(perldoc perldsc
)
为情况选择正确的数据结构,以及如何定义
它们。
答案 2 :(得分:4)
动态创建新的命名数组几乎不是一个好主意。启蒙书Higher-Order Perl的作者马克·多米努斯写了一篇three - part series,详细说明了这些陷阱。
对于这些数组,您需要考虑名称,因此请将它们放在哈希中:
sub create_arrays {
my($where,$n) = @_;
for (1 .. $n) {
$where->{"message$_"} = [];
}
}
有关显示结构的快速示例,请参阅下面的代码
my $n = @ARGV ? shift : 3;
my %hash;
create_arrays \%hash, $n;
use Data::Dumper;
$Data::Dumper::Indent = $Data::Dumper::Terse = 1;
print Dumper \%hash;
输出
$ ./prog.pl { 'message2' => [], 'message3' => [], 'message1' => [] }
指定不同数量的数组,我们得到
$ ./prog.pl 7 { 'message2' => [], 'message6' => [], 'message5' => [], 'message4' => [], 'message3' => [], 'message1' => [], 'message7' => [] }
键的顺序看起来很有趣,因为它们位于散列内,是一种无序的数据结构。
回想一下,[]
创建了对新匿名数组的引用,因此,例如,要向message2添加值,您需要编写
push @{ $hash{"message2"} }, "Hello!";
要打印它,你要写
print $hash{"message2"}[0], "\n";
也许你想知道所有数组的长度:
foreach my $i (1 .. $n) {
print "message$i: ", scalar @{ $hash{"message$i"} }, "\n";
}
有关如何在Perl中使用引用的更多详细信息,请参阅以下文档:
perldoc perlreftut
perldoc perlref
perldoc perldsc
答案 3 :(得分:2)
在编译语言中,变量没有名称。您在代码中看到的名称是与某些数字偏移相关联的唯一标识符。在message_2
之类的标识符中,'2'
仅用于使其成为唯一标识符。任何人都可以告诉您可以创建三个变量:message_125
,message_216
和message_343
。只要你能告诉你应该把什么放进去,它们的工作方式和message_1
......
变量的“名称”仅供您在编写代码时保持笔直。
动态语言通过不清除符号表来添加功能。但是符号表只是名称与值的关联。因为Perl为您提供如此便宜的列表和散列,所以不需要使用编程/逻辑方法来跟踪变量以允许灵活的运行时访问。
如果您看到自己命名列表@message1
,@message2
,...... - 这些项目的参考顺序不同,那么这些名称也一样好:{{1 },$message[1]
,....
此外,由于符号表通常是从名称到偏移量(在堆栈或堆中)映射,因此它实际上并不比在哈希中找到的键值对更多。因此,散列对于查找更多不同的名称同样有效。
$message[2]
我的意思是,如果您愿意,您可以将放入词法变量的所有内容存储到范围的单个哈希中,如果您不介意写一下:$h{messages} = [];
$h{replies} = [];
。但是你不会从Perl的隐式作用域管理中获益,而且跨语言,程序员更喜欢隐式作用域管理。
Perl允许进行符号操作,但多年来动态语言发现了混合的祝福。但是在Perl你有两个“观点”,给他们一个名字。因为您可以确定编译语言中的哪些代码可能比动态语言更好,所以已经确定更多的错误可以使用“编译透视图”来实现更多功能:因此您可以看到偏移管理的可用性并查找在核心Perl中给你的编译行为,如果你不需要,没有理由搞乱符号表。
动态创建数组非常简单:$h{variable_name}
。将它分配到内存中的某个位置,当我们不知道要存储多少时,就像这样容易:
[]
一次创建列表列表就像以下一样简单:
push @message, [];
表示@message = map { [] } 1..$num_lists;
中的某些指定值。