【问题标题】:How can I execute a given function on every element of a complicated data structure in Perl?如何在 Perl 中对复杂数据结构的每个元素执行给定的函数?
【发布时间】:2010-09-27 09:07:18
【问题描述】:

我想解码复杂数据结构中的所有 HTML 实体。基本上我正在寻找一个“超级地图()”功能。这是我目前所拥有的:

sub _html_decode {
    my $self = shift;
    my $ref = shift;

    if (ref($ref) eq "HASH") {
        $self->_html_decode_hash($ref)
    }
    if (ref($ref) eq "ARRAY") {
        $self->_html_decode_array($ref);
    }

}

sub _html_decode_array {
    my $self = shift;
    my $ref = shift;

    unless (@$ref) {return;}

    foreach (0 .. (scalar(@$ref) - 1)) {
        if (ref($ref->[$_]) eq "HASH") {
            $self->_html_decode_hash($ref->[$_]);
        }
        if (ref($ref->[$_]) eq "ARRAY") {
            $self->_html_decode_array($ref->[$_]);
        }
        else {
            $ref->[$_] = decode_entities($ref->[$_]);
        }
    }
}

sub _html_decode_hash {
    my $self = shift;
    my $ref = shift;

    unless (%$ref) {return;}

    while (my ($k, $v) = each %$ref) {
        if (ref($v) eq "HASH") {
            $self->_html_decode_hash($v);
        }
        if (ref($v) eq "ARRAY") {
            $self->_html_decode_array($v)
        }
        else {
            $ref->{$k} = decode_entities($v);
        }
    }
}

【问题讨论】:

    标签: perl data-structures recursion map


    【解决方案1】:

    Data::Rmap 似乎也这样做了。有人对这个模块有任何经验吗?

    【讨论】:

    • 没有经验,但听起来是解决问题的最佳方法。
    • 是的。我用过这个模块,强烈推荐它作为这类问题的首选。
    【解决方案2】:

    要对任意复杂数据结构的每个元素执行子例程,请查看访问者设计模式。基本上,您的数据结构是一个对象,它知道它仍需要处理哪些元素,并将您的子例程应用于它们。那里还有一些迭代器模式,因为你知道如何

    我的Netscape::Bookmarks 模块中有一个示例。该数据结构与几种不同类型的对象深度嵌套。通过使用访问者模式,大部分复杂性都消失了。

    除此之外,您可能还想查看我的Object::Iterate 模块。它有一个imap 函数,可以处理对象而不是列表。我从 Python 中窃取了 __next__ 的想法并将其应用到 Perl。

    【讨论】:

      【解决方案3】:

      我认为应该可以,但我还没有测试过。

      sub _html_decode {
          my ($self, $ref) = @_;
      
          if (ref($ref) eq "HASH") {
              for my $value (values %{$ref}) {
                  $self->_html_decode($value);
              }
          }
          elsif (ref($ref) eq "ARRAY") {
              for my $value (@{$ref}) {
                  $self->_html_decode($value);
              }
          }
          else {
              $_[1] = decode_entities($_[1]);
          }
      }
      

      我承认最后一部分并不漂亮。

      【讨论】:

        猜你喜欢
        • 2011-06-21
        • 2019-09-30
        • 1970-01-01
        • 2020-06-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-02-15
        • 1970-01-01
        相关资源
        最近更新 更多