如果我在Perl中有一个包含完整和顺序整数映射的哈希(即,从0到n的所有键都被映射到某个东西,除此之外没有键),是否有将其转换为数组的方法?
我知道我可以遍历键/值对并将它们放入一个新数组中,但有些东西告诉我应该有一个内置的方法来实现这一点。
答案 0 :(得分:21)
如果您的原始数据源是哈希:
# first find the max key value, if you don't already know it:
use List::Util 'max';
my $maxkey = max keys %hash;
# get all the values, in order
my @array = @hash{0 .. $maxkey};
或者,如果您的原始数据源是hashref:
my $maxkey = max keys %$hashref;
my @array = @{$hashref}{0 .. $maxkey};
使用此示例很容易测试:
my %hash;
@hash{0 .. 9} = ('a' .. 'j');
# insert code from above, and then print the result...
use Data::Dumper;
print Dumper(\%hash);
print Dumper(\@array);
$VAR1 = {
'6' => 'g',
'3' => 'd',
'7' => 'h',
'9' => 'j',
'2' => 'c',
'8' => 'i',
'1' => 'b',
'4' => 'e',
'0' => 'a',
'5' => 'f'
};
$VAR1 = [
'a',
'b',
'c',
'd',
'e',
'f',
'g',
'h',
'i',
'j'
];
答案 1 :(得分:15)
您可以使用values
函数从哈希中提取所有值:
my @vals = values %hash;
如果您想按特定顺序使用它们,那么您可以按所需顺序放置密钥,然后从中获取hash slice:
my @sorted_vals = @hash{sort { $a <=> $b } keys %hash};
答案 2 :(得分:13)
好吧,这不是“内置”但是有效。对于任何涉及“排序”的解决方案,它也是恕我直言,因为它更快。
map { $array[$_] = $hash{$_} } keys %hash; # Or use foreach instead of map
否则,效率会降低:
my @array = map { $hash{$_} } sort { $a<=>$b } keys %hash;
答案 3 :(得分:4)
Perl没有提供内置功能来解决您的问题。
如果您知道密钥涵盖特定范围0..N
,则可以利用以下事实:
my $n = keys(%hash) - 1;
my @keys_and_values = map { $_ => $hash{$_} } 0 .. $n;
my @just_values = @hash{0 .. $n};
答案 4 :(得分:2)
这会将%hashed_keys
中未定义的密钥保留为undef
:
# if we're being nitpicky about when and how much memory
# is allocated for the array (for run-time optimization):
my @keys_arr = (undef) x scalar %hashed_keys;
@keys_arr[(keys %hashed_keys)] =
@hashed_keys{(keys %hashed_keys)};
而且,如果你正在使用参考文献:
@{$keys_arr}[(keys %{$hashed_keys})] =
@{$hashed_keys}{(keys %{$hashed_keys})};
或者,更危险的是,因为它假设你所说的是真的(它可能并不总是真的......只是说'!):
@keys_arr = @hashed_keys{(sort {$a <=> $b} keys %hashed_keys)};
但这有点不合时宜。如果它们是以整数索引开头的,为什么它们现在都在哈希?
答案 5 :(得分:1)
$Hash_value =
{
'54' => 'abc',
'55' => 'def',
'56' => 'test',
};
while (my ($key,$value) = each %{$Hash_value})
{
print "\n $key > $value";
}
答案 6 :(得分:0)
正如DVK所说,没有内置的方法,但这样做可以解决问题:
my @array = map {$hash{$_}} sort {$a <=> $b} keys %hash;
或者这个:
my @array;
keys %hash;
while (my ($k, $v) = each %hash) {
$array[$k] = $v
}
基准来看哪个更快,我猜是第二个。
答案 7 :(得分:0)
my @array = @hash{ 0 .. $#{[ keys %hash ]} };
与scalar
方法不同,$#
与第一个元素$[
的默认索引非零的不太可能的情况相同。
当然,这意味着写一些愚蠢的东西,如此晦涩难懂:
my @array = @hash{ $[ .. $#{[ keys %hash ]} }; # Not recommended
但是总有远程机会有人需要它( wince )......
答案 8 :(得分:0)
@a = @h{sort { $a <=> $b } keys %h};
答案 9 :(得分:0)
我们可以写一下如下:
$j =0;
while(($a1,$b1)=each(%hash1)){
$arr[$j][0] = $a1;
($arr[$j][1],$arr[$j][2],$arr[$j][3],$arr[$j][4],$arr[$j][5],$arr[$j][6]) = values($b1);
$j++;
}
$ a1包含密钥和 $ b1包含值 在上面的例子中,我有Hash of array,数组包含6个元素。
答案 10 :(得分:0)
一种简单的方法是@array = %hash
例如,
my %hash = (
"0" => "zero",
"1" => "one",
"2" => "two",
"3" => "three",
"4" => "four",
"5" => "five",
"6" => "six",
"7" => "seven",
"8" => "eight",
"9" => "nine",
"10" => "ten",
);
my @array = %hash;
print "@array";
会产生以下输出,
3 3 9 9 5 5 8 8 2 2 4 4 1 1 10 10 7 7 0 0 6六个