簡體   English   中英

如何從Perl中的現有哈希創建匿名哈希?

[英]How can I create an anonymous hash from an existing hash in Perl?

如何從現有哈希創建匿名哈希?

對於數組,我使用:

@x = (1, 2, 3);
my $y = [@x];

但我找不到如何為哈希做同樣的事情:

my %x = ();
my $y = ???;

謝謝

為什么需要匿名哈希? 雖然答案告訴你各種方法可以制作一個匿名哈希,但我們不知道它們中的任何一個是否是你想要做的任何事情的正確解決方案。

如果您想要一個可以在不打擾原始數據的情況下修改的獨特副本,請使用Perl附帶的Storable中的dclone 它會創建數據結構的深層副本:

use Storable qw(dclone);
my $clone = dclone \%hash;

考慮戴夫韋伯的答案,但附加一層參考。 c的鍵的值是另一個哈希引用:

use Data::Dumper;

my %original = ( a => 1, b => 2, c => { d => 1 } );
my $copy = { %original };

print 
    "Before change:\n\n",
    Data::Dumper->Dump( [ \%original], [ qw(*original) ] ),
    Data::Dumper->Dump( [ $copy ], [ qw(copy) ] ),
    ;

$copy->{c}{d} = 'foo';

print 
    "\n\nAfter change:\n\n",
    Data::Dumper->Dump( [ \%original], [ qw(*original) ] ),
    Data::Dumper->Dump( [ $copy ], [ qw(copy) ] ),
    ;

通過檢查輸出,您會看到即使您有匿名哈希,它仍然鏈接到原始:

Before change:

%original = (
              'c' => {
                       'd' => 1
                     },
              'a' => 1,
              'b' => 2
            );
$copy = {
          'c' => {
                   'd' => 1
                 },
          'a' => 1,
          'b' => 2
        };


After change:

%original = (
              'c' => {
                       'd' => 'foo'
                     },
              'a' => 1,
              'b' => 2
            );
$copy = {
          'c' => {
                   'd' => 'foo'
                 },
          'a' => 1,
          'b' => 2
        };
my $new_hash = { %existing_hash };

請注意,此解決方案不會進行深層復制。 閱讀brian的答案進行解釋。

我想你在這里需要小心。 考慮以下哈希:

my %hash = (1 => 'one',2 => 'two');

有兩種方法可以從中獲得參考:

my $ref = \%hash;
my $anon = {%hash};

$ref是對原始哈希的引用,可以類似於%hash $anon是對原始哈希的匿名副本的引用; 它將具有相同的數據,但更改它不會更改原始哈希,反之亦然。

因此,例如,從這兩個語句開始將具有相同的輸出

print $ref->{1},"\n";
> one
print $anon->{1},"\n";
> one

但是,如果我更改原始哈希:

$hash{1} = "i";

他們兩個print語句將輸出不同的值:

print $ref->{1},"\n";
> i
print $anon->{1},"\n";
> one

如果你有

my %hash = ...

那么你可以做到

my $hashref = \%hash;

這里似乎有兩件事情,答案分為回答兩個不同的可能問題。

  1. 你想要一個匿名哈希。 簡單。 你可以一步完成。
  2. 您需要現有哈希的匿名副本。 正如Dave Webb和brian建議的那樣,如果你想要一個引用,可能就是這樣 ,但是你不想篡改原始哈希。 也很容易。 (嗯,不完全是這樣的:看看brian關於深拷貝細節的答案。)

如果你想要1,請執行以下操作:

my $hash_ref = { foo => 1, bar => 2 };

如果你想要2,請執行以下操作:

my %hash = ( foo => 1, bar => 2 );

# Then later
my $anon_copy_hash_ref = { %hash };

(這些名字不適合黃金時段。)我的副本也沒有為黃金時間做好准備。 請參閱brian的帖子,以獲得更全面,更精確的討論。

使用:

$hashref = {};

快速/簡單的方法來實現深層復制:

use FreezeThaw qw(freeze thaw);
$new = thaw freeze $old;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM