基于activePerl 5.8
#!C:\Perl\bin\perl.exe
use strict;
use warnings;
# declare a new hash
my %some_hash;
%some_hash = ("foo", 35, "bar", 12.4, 2.5, "hello",
"wilma", 1.72e30, "betty", "bye\n");
my @any_array;
@any_array = %some_hash;
print %some_hash;
print "\n";
print @any_array;
print "\n";
print $any_array[0];
print "\n";
print $any_array[1];
print "\n";
print $any_array[2];
print "\n";
print $any_array[3];
print "\n";
print $any_array[4];
print "\n";
print $any_array[5];
print "\n";
print $any_array[6];
print "\n";
print $any_array[7];
print "\n";
print $any_array[8];
print "\n";
print $any_array[9];
以此输出
D:\learning\perl>test.pl
bettybye
bar12.4wilma1.72e+030foo352.5hello
bettybye
bar12.4wilma1.72e+030foo352.5hello
betty
bye
bar
12.4
wilma
1.72e+030
foo
35
2.5
hello
D:\learning\perl>
我的示例代码中的元素打印顺序是什么?
在Perl中打印混合(字符串,数字)哈希时要遵循的任何规则?谢谢。
bar12.4wilma1.72e+030foo352.5hello
[更新]
在你们的帮助下,我更新了以下代码。
#!C:\Perl\bin\perl.exe
use strict;
use warnings;
# declare a new hash
my %some_hash;
%some_hash = ("foo", 35, "bar", 12.4, 2.5, "hello",
"wilma", 1.72e30, "betty", "bye");
my @any_array;
@any_array = %some_hash;
print %some_hash;
print "\n";
print "\n";
print @any_array;
print "\n";
print "\n";
my @keys;
@keys = keys %some_hash;
for my $k (sort @keys)
{
print $k, $some_hash{$k};
}
输出
D:\learning\perl>test.pl
bettybyebar12.4wilma1.72e+030foo352.5hello
bettybyebar12.4wilma1.72e+030foo352.5hello
2.5hellobar12.4bettybyefoo35wilma1.72e+030
D:\learning\perl>
最终,在调用keys
和sort
函数后。哈希键打印遵循以下规则
2.5hellobar12.4bettybyefoo35wilma1.72e+030
答案 0 :(得分:22)
哈希的元素按其内部顺序打印出来,不能依赖它们,并且会随着元素的添加和删除而改变。如果您需要某种顺序的哈希的所有元素,请对键进行排序,并使用该列表来索引哈希。
如果您正在寻找一个按顺序保存其元素的结构,可以使用数组,也可以在CPAN上使用其中一个有序哈希值。
您可以依赖列表上下文哈希扩展的唯一顺序是key =>价值对将在一起。
答案 1 :(得分:9)
散列的键以明显随机的顺序返回。实际的随机顺序在未来的Perl版本中可能会发生变化,但保证与值或每个函数产生的顺序相同(假设散列未被修改)。从Perl 5.8.1开始,出于安全原因,即使在不同的Perl运行之间,顺序也不同(参见Algorithmic Complexity Attacks in perlsec)。
...
Perl从未保证任何散列键的排序,并且在Perl 5的生命周期中排序已经多次改变。此外,散列键的排序一直并且继续受插入顺序的影响
另请注意,虽然哈希元素的顺序可能是随机的,但这种“伪目标”不应该用于随机填充列表的应用程序(请使用List :: Util :: shuffle(),请参阅{{3自Perl 5.8.0以来的标准核心模块;或CPAN模块List::Util),或用于生成排列(使用例如CPAN模块Algorithm::Numerical::Shuffle或Algorithm::Permute),或任何加密应用程序。
注意:由于您正在评估列表上下文中的哈希,因此 至少保证每个键后跟其对应的值;例如你永远不会看到a 4 b 3 c 2 d 1
的输出。
答案 2 :(得分:3)
我查看了你的代码并做了一些我认为你会发现有用的笔记。
use strict;
use warnings;
# declare a new hash and initialize it at the same time
my %some_hash = (
foo => 35, # use the fat-comma or '=>' operator, it quotes the left side
bar => 12.4,
2.5 => "hello",
wilma => 1.72e30,
betty => "bye", # perl ignores trailing commas,
# the final comma makes adding items to the end of the list less bug prone.
);
my @any_array = %some_hash; # Hash is expanded into a list of key/value pairs.
print "$_ => $some_hash{$_}\n"
for keys %some_hash;
print "\n\n", # You can print multiple newlines in one string.
"@any_array\n\n"; # print takes a list of things to print.
# In print @foo; @foo is expanded into a list of items to print.
# There is no separator between the members of @foo in the output.
# However print "@foo"; interpolates @foo into a string.
# It inserts spaces between the members of the arrays.
# This is the block form of 'for'
for my $k (sort keys %some_hash)
{
# Interpolating the variables into a string makes it easier to read the output.
print "$k => $some_hash{$k}\n";
}
哈希提供无序的,通过字符串键访问数据。
Arrays提供对有序数据的访问。使用数字索引可以随机访问。
如果需要保留一组值的顺序,请使用数组。如果您需要通过关联名称查找组成员,请使用哈希。
如果您需要同时使用这两种结构:
# Keep an array of sorted hash keys.
my @sorted_items = qw( first second third fourth );
# Store the actual data in the hash.
my %item;
@item{ @sorted_items } = 1..4; # This is called a hash slice.
# It allows you to access a list of hash elements.
# This can be a very powerful way to work with hashes.
# random access
print "third => $item{third}\n";
# When you need to access the data in order, iterate over
# the array of sorted hash keys. Use the keys to access the
# data in the hash.
# ordered access
for my $name ( @sorted_items ) {
print "$name => $item{$name}\n";
}
查看代码示例,我看到了一些您可能想要处理的事情。
for
和while
这样的循环结构来减少重复的代码。答案 3 :(得分:2)
元素(几乎可以肯定)按照它们在(在内部)在哈希表本身中出现的顺序打印出来 - 即基于其键的哈希值。
如果您非常关心订单,则遵循的一般规则是使用哈希表以外的其他内容。
答案 4 :(得分:2)
不一定(必然)以排序方式检索哈希值。如果你想要它们排序,你必须自己做:
use strict;
use warnings;
my %hash = ("a" => 1, "b" => 2, "c" => 3, "d" => 4);
for my $i (sort keys %hash) {
print "$i -> $hash{$i}\n";
}
使用keys
从哈希中检索所有密钥,然后使用sort
对其进行排序。是的,我知道,那个疯狂的拉里沃尔家伙,曾经想过要把他们称为那个?: - )
输出:
a -> 1
b -> 2
c -> 3
d -> 4
答案 5 :(得分:1)
对于大多数实际用途,哈希表(不仅仅是Perl哈希变量,而是一般的哈希表)的顺序可以被认为是随机的。
实际上,根据哈希实现,订单实际上可能是确定性的。 (也就是说,如果你多次运行程序,每次都以相同的顺序将相同的项目放入哈希表中,那么每次都会以相同的顺序存储它们。)我知道Perl哈希曾经有过这个特性,但是我不确定当前的版本。在任何情况下,散列键顺序不是在需要随机性的情况下使用的可靠随机源。
简短版本,然后:
如果您关心订单(或缺乏订单),请不要使用哈希。如果你想要一个固定的订单,它将是有效的随机,如果你想要一个随机的订单,它将被有效地修复。
答案 6 :(得分:0)
哈希定义没有排序属性。事情发生的顺序是不可预测的。
答案 7 :(得分:0)
如果你疯了并且你的哈希值没有重复值,并且你需要对值进行排序,你可以在它上面调用reverse。
my %hash = ("a" => 1, "b" => 2, "c" => 3, "d" => 4);
my %reverse_hash = reverse %hash;
print $_ for sort keys %reverse_hash;
警告是唯一的值部分,重复将被覆盖,只有一个值进入。