Perl,将哈希转换为数组

时间:2010-05-25 18:09:23

标签: perl hash arrays

如果我在Perl中有一个包含完整和顺序整数映射的哈希(即,从0到n的所有键都被映射到某个东西,除此之外没有键),是否有将其转换为数组的方法?

我知道我可以遍历键/值对并将它们放入一个新数组中,但有些东西告诉我应该有一个内置的方法来实现这一点。

11 个答案:

答案 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)

结合FMEther的答案可以避免定义其他不必要的标量:

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六个