【问题标题】:How to insert hash into hash in Perl如何在 Perl 中将哈希插入哈希
【发布时间】:2011-11-22 15:24:15
【问题描述】:

我在主文件的某处定义了一个简单的哈希

our %translations = (
    "phrase 1" => "translation 1",
    # ... and so on 
    );

在另一个文件中,我想添加更多翻译。也就是说,我想做这样的事情:

push our %translations, (
    "phrase N" => "blah-blah",
    # ....
    "phrase M" => "something",
    );

当然,这段代码不起作用:push 不适用于哈希。所以我的问题是:将值的散列插入现有散列的简单而优雅的方法是什么?

我不想诉诸于

$translations{"phrase N"} = "blah-blah";
# ....
$translations{"phrase M"} = "something";

因为在 Perl 中,您应该能够在代码中没有过多重复的情况下做事...

【问题讨论】:

    标签: perl hash


    【解决方案1】:
    %translations = (%translations, %new_translations);
    

    【讨论】:

    • 与 yi_H 的回答原理相同,但表明您可以在现有哈希上执行此操作,而不仅仅是在创建 %translations
    【解决方案2】:

    您可以使用 keysvalues 函数分配给哈希切片。只要在调用之间没有修改散列,keys 将按照 values 返回值的顺序返回键。

    our %translations = (
      "phrase 1" => "translation 1",
    );
    
    { # Braces just to restrict scope of %add
      my %add = (
        "phrase N" => "blah-blah",
        "phrase M" => "something",
      );
      @translations{keys %add} = values %add;
    }
    
    # Or, using your alternate syntax:
    @translations{keys %$_} = values %$_ for {
      "phrase N" => "blah-blah",
      "phrase M" => "something",
    };
    

    【讨论】:

    • 这有帮助!我什至可以写成@translations{keys %$_} = values $%_ for {"phrase N" => "blah-blah", ...};
    • 我没有想到这种语法,但它是一个聪明的捷径。循环使它可能效率降低,但我怀疑差异是可测量的。
    • 嗯,它是对单个元素的循环。将匿名哈希分配给 $_ 变量的更方便的方法。
    【解决方案3】:

    您可以分配给哈希切片:

    @translations{@keys} = @values;
    

    或使用来自另一个哈希的数据:

    @translations{keys %new} = values %new;
    

    【讨论】:

    • 但是,由于我添加了许多新键,因此很难跟踪键与其值之间的对应关系(哪个翻译对应哪个短语)。
    • @user958624:您可以将数组用于键和值(请参阅更新)
    【解决方案4】:
    %translations = (
        "phrase N" => "blah-blah",
        # ....
        "phrase M" => "something",
        %translations
        );
    

    【讨论】:

    • 这会复制整个哈希吗?也就是说,假设%translations 已经包含数千个条目。您是否会创建一个临时哈希(“短语 N”=>...、“短语 M”=>...、 的副本),然后将此临时哈希分配给 %translations?如果是这样,那么使用这种方法将会有很大的开销,如果不是,那么它似乎很简单!
    • @user958624:是的,确实如此。从这些子列表构造一个新的列表值并分配给%translations
    【解决方案5】:

    Hash::Merge 是另一种选择:https://metacpan.org/module/Hash::Merge

    另外 - 不要太担心复制哈希的优化 - 如果它成为一个问题,然后再调查它。首先尝试编写清晰易读和可维护的代码。包含字符串值的几千个键的哈希并不大!

    您在问题中没有指定的是,是否会有任何键冲突(即是否会从文件中读取两个“短语 1”...?

    【讨论】:

    • Hash::Merge 太过分了,除非你有嵌套的数据结构或需要对重复键进行特殊处理。
    • 我同意,在这种情况下,但知道它的存在很有用,所以我想我只是提一下。
    【解决方案6】:

    我知道,已经说过了。但我想强调一个方面:

    以下会覆盖您哈希中的现有值:

    %translations = (
        %translations,
        "phrase N" => "blah-blah",
        "phrase M" => "something"
        );
    

    以下没有:

    %translations = ( 
        "phrase N" => "blah-blah",
        "phrase M" => "something",
        %translations
        );
    

    示例 1

    my %translations = ( a => 'first', b => 'second');
    %translations = (%translations, a => 'at first', c => 'third');
    

    现在你有:

    "a" => "at first"  # its overwritten by the new value
    "b" => "second"
    "c" => "third"
    

    示例 2

    my %translations = ( a => 'first', b => 'second');
    %translations = (a => 'at first', c => 'third', %translations);
    

    现在你有:

    "a" => "first"  # the old value is not overwritten
    "b" => "second"
    "c" => "third"
    

    【讨论】:

      猜你喜欢
      • 2023-04-07
      • 1970-01-01
      • 2012-11-11
      • 2011-04-20
      • 1970-01-01
      • 1970-01-01
      • 2011-06-14
      • 2013-12-20
      相关资源
      最近更新 更多