arrays - 在多维数组中删除后不能有普通数组

标签 arrays perl

多维数组中的元素被移除后,我们如何得到普通数组?

@p=();
my @l=([9,7],[3,4]);

push(@p,['FOO',[@l]]);
push(@p,['BAR',[[8,0]]]);
splice(@$_,0,1) for @p;
print "\n",@$_ for @p;

ARRAY(0x5624cf01e340)
ARRAY(0x5624cf028d78)

我们如何在内部/二维一维上拥有 1x2 大小的简单/普通二维数组。换句话说,如何将它线性化成这样?

最佳答案

必须取消引用数组引用的元素,并复制数据。对于单个级别:

@ary = map { ref eq "ARRAY" ? @$_ : $_ } @ary;

ref内置默认采用 $_。还可以考虑使用 Scalar::Util 中的 reftype , 反而。然后还查看来自 Ref::Utilis_arrayref .在简单直接的情况下,内置函数就可以了。

如果有更深的层次,请在每个层次上使用上面的内容。对于问题的追求,从两层深度输入数据中保留一层嵌套:

for my $elem (@p) { 
    @$elem = map { ref eq "ARRAY" ? @$_ : $_ } @$elem;
}

由于 $elem@p 的当前元素设置了别名,因此这段代码就地更改了数组。

如果有更多级别,可能深度不同,可以递归或迭代处理。粗略的实现:

递归:

sub flatten_recurse { 
    return map { ref eq 'ARRAY' ? flatten_recurse(@$_) : $_ } @_ 
}

这在大型数据结构上可能代价高昂(但只有在确实如此的情况下才担心)。

迭代:

sub flatten_iter { 
    my @deque = @_; 
    my @flat;
    while (@deque) {
        my $front = shift @deque;
        if (ref($front) eq 'ARRAY') {
            unshift @deque, @$front;
        } else {
            push @flat, $front;
        }
    }   
    return \@flat;
}

这里还可以使用 poppush 的不同组合。在将复杂结构简化为扁平化结构时,以上内容尽可能保持顺序。

如果还有其他复杂性,如其他类型的引用(它们本身包含要解包的数组引用),则需要相应地进行调整。还需要添加检查,特别是对于循环引用。参见例如 this SO pagethis perlmonks page .

关于arrays - 在多维数组中删除后不能有普通数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70501634/

相关文章:

php - 在 PHP 中连接 3 个表以创建一个数组

sql - 从数组中获取下一个项目

c - 数组的段错误

c++ - 将文件内容复制到字符串

perl - 查找多维数组大小

perl - 如何使用Net::OpenSSH安全地写入远程文件

javascript - 调用 $.get 方法时如何使 javascript 变量成为全局变量?

mysql - Perl 将数据从一个数据库复制到另一个数据库

arrays - 如何绕过 Perl 中 foreach 循环的范围

perl - 在 Perl 中对文件名进行排序?