我如何在深层嵌套但任意的数据结构中替换值



i具有任意的数据结构。该形式通常相似,因为它由阵列和哈希组成,大约四个级别,我想更改约2至6个值。一个典型的例子:

$VAR1 = [
          undef,
          [
            {
              '0' => 'some string'
            }
          ],
          undef,
          [
            undef,
            {
              '1033' => 'another string '
            }
          ]
        ];

我非常了解语法足以访问这两个值并在此特定示例(或其他任何示例)中更改它们,但是从一种用途到下一个示例,将会以硬编码的表达式失败的方式改变。

这感觉就像是一个简单的子,递归运行,但是一旦发现数据结构的元素是数组或哈希,我就不知道如何通过参考将元素传递到下一个递归调用中因此可以以非仿期方式进行修改。以下代码会递归失败(尽管如果不循环,它可以在顶级数组中更改浅价值,并且此更改粘贴):

sub deep_nested_replace {
    my ($d, $string) = @_;
    if (ref($d) eq 'ARRAY') {
        for (my $i=0; $i<scalar @$d; $i++) {
            deep_nested_replace($d->[$i], $string);
        }
    }
    elsif (ref($d) eq 'HASH') {
        foreach my $k (keys %$d) {
            deep_nested_replace($d->{$k}, $string);
        }
    }
    elsif (defined $d) {
        $d = $string;
    }
}

我如何完成这项工作?如果这是错误的方法,什么是正确的方法?

带有函数参数的@_数组包含传递给该函数的标量(或其他明确引用)的别名。对其进行修改将影响呼叫者数据。grepmap中的$_相同。这是您有时需要小心的其他编程语言的东西。

但是,通过将一个标量变量的分配到另一个标量变量,如惯用性my ($d, $string) = @_所示,标量值从一个变量复制到另一个变量。

如果要影响传递给呼叫者函数的标量值,则可以直接与@_数组及其元素一起工作。

sub deep_nested_replace {
    my ($d, $string) = @_;
    if (ref($d) eq 'ARRAY') {
        deep_nested_replace($_, $string) for @$d;
    }
    elsif (ref($d) eq 'HASH') {
        deep_nested_replace($_, $string) for values %$d;
    }
    elsif (defined $d) {
        $_[0] = $string;
    }
}

最新更新