多维数组中的元素被移除后,我们如何得到普通数组?
@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::Util 的 is_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;
}
这里还可以使用 pop
和 push
的不同组合。在将复杂结构简化为扁平化结构时,以上内容尽可能保持顺序。
如果还有其他复杂性,如其他类型的引用(它们本身包含要解包的数组引用),则需要相应地进行调整。还需要添加检查,特别是对于循环引用。参见例如 this SO page和 this perlmonks page .
关于arrays - 在多维数组中删除后不能有普通数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70501634/