简化递归函数

时间:2015-12-07 16:49:32

标签: perl recursion code-organization

虽然围绕recursion缠绕我的大脑,但我希望通过以下简单的问题来更好地理解递归本身,同时也在TIMTOWTDI的精神中以其他或更好的方式来实现我的目标。

问题非常简单,给定一个复杂的Perl数据结构,$cds(保证以HASH开头,嗯,是否会产生差异?),我希望遍历{{1}并删除单级数组。

我从下面开始,工作得很好......

$cds

...但我不知何故觉得代码可能更简单,更短。在对类似问题进行针刺后,我修改为:

sub reduce_1level
{
    my $cds = shift;

    if (ref $cds eq 'HASH')
    {
        foreach my $key (keys %$cds)
        {
            if (ref $cds->{$key} eq 'ARRAY')
            {
                if (@{$cds->{$key}} == 1)
                {
                    $cds->{$key} = $cds->{$key}[0];
                }
                else
                {
                    reduce_1level ($cds->{$key});
                }
            }
            elsif (ref $cds->{$key} eq 'HASH')
            {
                reduce_1level ($cds->{$key});
            }
        }
    }
    elsif (ref $cds eq 'ARRAY')
    {
        foreach (@$cds)
        {
            reduce_1level ($_) if ref;
        }
    }
}

我想知道还有什么方法可以更好地实现缩进目标?

1 个答案:

答案 0 :(得分:4)

忘记复杂性。它甚至不正确。

有些调用处理数据结构的两个级别,因此您应该有重复的代码。但你不是。因此,并未消除以下所有单元素数组:

{ foo => [ [ 3 ] ] }

请勿尝试在同一个电话中处理两个级别。

sub reduce_1level {
    our $cds; local *cds = \shift;   # alias $cds = shift;

    my $reftype = ref($cds)
        or return;

    if ($reftype eq 'HASH') {
        reduce_1level($_) for values %$cds;
    }
    elsif ($reftype eq 'ARRAY') {
        if (@$cds == 1) {
            $cds = $cds->[0];
            reduce_1level($cds);
        } else {
            reduce_1level($_) for @$cds;
        }
    }
    else {
        die("Unsupported reference type $reftype\n");
    }
}