展平多维数组的最简单方法是什么?
答案 0 :(得分:36)
使用地图进行一级展平
$ref = [[1,2,3,4],[5,6,7,8]]; # AoA
@a = map {@$_} @$ref; # flattens it
print "@a"; # 1 2 3 4 5 6 7 8
答案 1 :(得分:15)
使用List::Flatten
似乎最简单:
use List::Flatten;
my @foo = (1, 2, [3, 4, 5], 6, [7, 8], 9);
# @foo contains 6 elements, 2 of them are array references
my @bar = flat @foo;
# @bar contains 9 elements, same as (1 .. 9)
使用List::Flatten::Recursive
递归执行。
答案 2 :(得分:9)
最简单 和最自然的方式是迭代值并使用@运算符“取消引用”/“解压缩”任何现有的嵌套值以获取组成部分。然后对遇到的每个参考值重复该过程。
这类似于Viajayenders解决方案,但适用于数组引用中尚未存在的值以及任何嵌套级别:
sub flatten {
map { ref $_ ? flatten(@{$_}) : $_ } @_;
}
尝试测试它:
my @l1 = [ 1, [ 2, 3 ], [[[4]]], 5, [6], [[7]], [[8,9]] ];
my @l2 = [ [1,2,3,4,5], [6,7,8,9] ];
my @l3 = (1, 2, [3, 4, 5], 6, [7, 8], 9); # Example from List::Flatten
my @r1 = flatten(@l1);
my @r2 = flatten(@l1);
my @r3 = flatten(@l3);
if (@r1 ~~ @r2 && @r2 ~~ @r3) { say "All list values equal"; }
答案 3 :(得分:3)
如果数据总是像一个例子,我也推荐List :: Flatten。
但是数据有超过2个嵌套数组,不能正常工作。
喜欢@foo = [1, [2, [3, 4, 5]]]
在这种情况下,你应该为它编写递归代码。
轰鸣声怎么样。
sub flatten {
my $arg = @_ > 1 ? [@_] : shift;
my @output = map {ref $_ eq 'ARRAY' ? flatten($_) : $_} @$arg;
return @output;
}
my @foo = (1, 2, [3, 4, 5, [6, 7, 8]], 9);
my $foo = [1, 2, [3, 4, 5, [6, 7, 8]], 9];
my @output = flatten @foo;
my @output2 = flatten $foo;
print "@output";
print "@output2";
答案 4 :(得分:2)
在包含以下内容时展平多维数组的最简单方法: 数组 2.数组引用 3.标量值 4. 标量引用
sub flatten {
map { ref $_ eq 'ARRAY' ? flatten(@{$_}) :
ref $_ eq 'SCALAR' ? flatten(${$_}) : $_
} @_;
}
另一个扁平子回答在标量引用上崩溃。
答案 5 :(得分:0)
有些事情:
my $i = 0;
while ($i < scalar(@array)) {
if (ref @array[$i] eq 'ARRAY') {
splice @array, $i, 1, @$array[$i];
} else {
$i++;
}
}
我是盲目地写的,不知道它是否真的有效,但你应该明白这一点。
答案 6 :(得分:0)
与Vijayender的解决方案相同,但适用于包含arrayrefs和标量的混合数组。
$ref = [[1,2,3,4],[5,6,7,8],9,10];
@a = map { ref $_ eq "ARRAY" ? @$_ : $_ } @$ref;
print "@a"
当然你可以将它扩展为dereference hashrefs:
@a = map { ref $_ eq "ARRAY" ? @$_ : ref $_ eq "HASH" ? %$_: $_ } $@ref;
或使用grep来清除垃圾:
@a = map { @$_} grep { ref $_ eq 'ARRAY' } @$ref;
从List :: MoreUtils 0.426开始,我们有一个 arrayify 函数,它递归地展平数组:
@a = (1, [[2], 3], 4, [5], 6, [7], 8, 9);
@l = arrayify @a; # returns 1, 2, 3, 4, 5, 6, 7, 8, 9
之前已经介绍但是被打破了。