复制前N个键和数组哈希值

时间:2013-03-30 20:41:46

标签: arrays perl hash subroutine

我有一个数组哈希。

%HoA = (
    'C1' =>  ['1', '3', '3', '3'],
    'C2' => ['3','2'],
    'C3' => ['1','3','3','4','5','5'],
    'C4'  => ['3','3','4'],
    'C5' => ['1'],
);

我想编写一个子例程,它返回一个数组的“子副本”哈希,它包含数组原始哈希的前N个键(及其值)。

像这样的东西

my %HoA2 = new_partition(\%HoA, 3);

它返回一个新的HoA数据结构:

%HoA = (
    'C1' =>  ['1', '3', '3', '3'],
    'C2' => ['3','2'],
    'C3' => ['1','3','3','4','5','5'],
 );

有没有办法在不使用模块的情况下划伤?

2 个答案:

答案 0 :(得分:3)

没有“前N个元素”,因为散列键的顺序没有定义,因此不能依赖。

如果你想要任何三个元素而不是前三个元素,你可以使用

%HoA = @HoA{ ( keys %HoA )[0..2] };

答案 1 :(得分:3)

正如已经正确陈述的那样,哈希中元素的顺序是未定义的。但是如果你可以在元素上强加自己的顺序,那么提取你需要的元素就足够了:

my %HoA = (
    'C1' => ['1', '3', '3', '3'],
    'C2' => ['3','2'],
    'C3' => ['1','3','3','4','5','5'],
    'C4' => ['3','3','4'],
    'C5' => ['1'],
);

# Use an array slice to grab the first 3 keys from a sorted list of %HoA keys.
# Use map to create a new hash that contains the keys and the values from the
# original hash:
my %HoA2 = map { $_ => $HoA{$_} } (sort keys %HoA)[0..2];

# Alternatively, specify the exact keys that you require:
my %HoA3 = map { $_ => $HoA{$_} } qw(C1 C2 C3);

# { C1 => [1, 3, 3, 3], C2 => [3, 2], C3 => [1, 3, 3, 4, 5, 5] }

<强>更新

正如Borodin所指出的,上述方法会复制引用,因此对一个哈希的更改将反映在另一个哈希中:

push @{$HoA{C1}}, 9;

# %HoA2 and %HoA3:
# { C1 => [1, 3, 3, 3, 9], C2 => [3, 2], C3 => [1, 3, 3, 4, 5, 5] }

为防止这种情况,请复制数组本身:

my %HoA4 = map { $_ => [@{ $HoA{$_} }] } qw(C1 C2 C3);