【问题标题】:Inserting one hash into another using Perl使用 Perl 将一个散列插入另一个散列
【发布时间】:2016-12-15 14:36:58
【问题描述】:

我尝试了许多不同版本的使用 push 和 splice,但似乎无法根据需要组合两个哈希。尝试将第二个哈希值插入到“Item”数组中的第一个哈希值中:

(
  ItemData => { Item => { ItemNum => 2, PriceList => "25.00", UOM => " " } },
)
(
  Alternate => {
    Description  => "OIL FILTER",
    InFile       => "Y",
    MfgCode      => "FRA",
    QtyAvailable => 29,
    Stocked      => "Y",
  },
)

我需要将第二个“Alternate”哈希插入到第一个哈希的“Item”数组中以获得此结果:

(
  ItemData => {
    Item => {
      Alternate => {
        Description  => "OIL FILTER",
        InFile       => "Y",
        MfgCode      => "FRA",
        QtyAvailable => 29,
        Stocked      => "Y",
      },
      ItemNum => 2,
      PriceList => "25.00",
      UOM => " ",
    },
  },
)

有人可以建议我如何做到这一点吗?

【问题讨论】:

  • 这看起来很像 XML。是吗?
  • 我也想说@Sobrique。可能是 XML::Simple。
  • 好的。我的建议是回溯,不要那样做。 XML::Simple 是一条通往痛苦的道路。如果您发布XML,我可以向您展示一个示例,该示例将它们拼接在一起,而不会在来回转换中固有的数据丢失。
  • 如果可以避免的话,永远不要使用XML::Simple,即使你不能,你也应该索要危险金。模块自己的文档说“你真的不想在新代码中使用这个模块”“不鼓励在新代码中使用这个模块”。请阅读Why is XML::Simple "Discouraged"?
  • 虽然XML::Simple读取 XML 文档时效果不佳,但使用XMLout 创建XML 文档时要差得多。由于这本质上是您的要求,我相信您应该改用XML::Twig。 API 很广泛,但是 XML 数据并不像XML::Simple 试图弄清的那么简单。还有XML::LibXML。不太平易近人,但XML::Simple的作者写了Perl XML::LibXML by Example,有助于顺利转移。

标签: perl hash


【解决方案1】:

假设您有两个哈希引用,这很简单。

my $item = {
    'ItemData' => {
        'Item' => {
            'PriceList' => '25.00',
            'UOM'       => ' ',
            'ItemNum'   => '2'
        }
    }
};

my $alt = {
    'Alternate' => {
        'MfgCode'      => 'FRA',
        'Description'  => 'OIL FILTER',
        'Stocked'      => 'Y',
        'InFile'       => 'Y',
        'QtyAvailable' => '29'
    }
};

$item->{ItemData}->{Item}->{Alternate} = $alt->{Alternate};

这里的诀窍不是将$alt 实际合并到$item 的某个部分,而是只取您想要的特定部分并将其放在您想要的位置。我们从$alt 中取出Alternate 键并将其内容放入$item 内部的新Alternate 键中。

Adam Millerchip 在因此删除的评论中指出这不是副本。如果您在将$alt->{Alternative} 粘贴到$item 后更改了$alt->{Alternative} 内部的任何键,则$item 内部的数据也会更改,因为我们正在处理引用。

$item->{ItemData}->{Item}->{Alternate} = $alt->{Alternate};
$alt->{Alternate}->{InFile} = 'foobar';

这实际上也会将 $item->{ItemData}->{Item}->{Alternate}->{InFile} 的值更改为 foobar,如下所示。

$VAR1 = {
          'ItemData' => {
                          'Item' => {
                                      'ItemNum' => '2',
                                      'Alternate' => {
                                                       'Stocked' => 'Y',
                                                       'MfgCode' => 'FRA',
                                                       'InFile' => 'foobar',
                                                       'Description' => 'OIL FILTER',
                                                       'QtyAvailable' => '29'
                                                     },
                                      'UOM' => ' ',
                                      'PriceList' => '25.00'
                                    }
                        }
        };

引用应该这样做,因为它们只引用某些东西。这就是他们的优点。

要制作真正的副本,您需要取消引用并创建一个新的匿名哈希引用。

#                                        create a new ref 
#                                          deref
$item->{ItemData}->{Item}->{Alternate} = { %{ $alt->{Alternate} } };

这将创建一个浅拷贝。 Alternate 键内的值将是副本,但如果它们包含引用,则不会复制,而是引用。


如果您确实想要合并更大的数据结构,其中需要合并多个键的内容,请查看Hash::Merge

【讨论】:

  • @AdamMillerchip:我知道你不是在“证明一个观点”,这意味着一些更具战斗性的东西。我可能应该使用“演示”。如果没有相关的代码和输出,您的帖子将在此处成为有价值的评论。
  • 正如亚当在他删除的答案中所写,您应该指出浅拷贝的危险。你也应该感谢他的推动。
  • @Borodin 更好?现在已经很长了,并且与 refs 的处理比 OP 试图解决的问题更多。我实际上并不认为他们会遇到这种情况,因为他们似乎在做一次性的事情。
  • 嗯。我没有在任何地方使用“更好”吗?我赞成您的回答,但我认为这可能与有关复制参考的常见警告有关。亚当删除的帖子会是一个有用的评论。
  • 啊,对不起 :-s 如果您的意思是“(那)更好”,那么是的,那是理想的!干得好。
猜你喜欢
  • 1970-01-01
  • 2014-10-23
  • 2016-09-04
  • 2014-07-27
  • 2011-05-08
  • 2016-10-17
  • 1970-01-01
  • 2011-02-15
  • 2023-03-07
相关资源
最近更新 更多