Какой самый простой способ сгладить многомерный массив?
Perl: Каков самый простой способ сгладить многомерный массив?
Ответ 1
Использование 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
Один уровень выравнивания с использованием карты
$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
Ответ 3
Самый простой и наиболее естественный способ - перебирать значения и использовать оператор @для "разыменования" / "распаковать" любые существующие вложенные значения, чтобы получить составные части. Затем повторите процесс для каждого опорного значения встречаются.
Это похоже на решение 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"; }
Ответ 4
Если данные всегда как пример, я рекомендую List:: Flatten тоже.
но данные имеют более 2 вложенных массивов, плоская работа cant't.
like @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";
Ответ 5
Самый простой способ сгладить многомерный массив, когда он включает: 1. массивы 2. ссылки на массивы 3. Скалярные значения 4. Скалярные ссылки
sub flatten {
map { ref $_ eq 'ARRAY' ? flatten(@{$_}) :
ref $_ eq 'SCALAR' ? flatten(${$_}) : $_
} @_;
}
Другой сглаженный вспомогательный ответ падает на скалярные ссылки.
Ответ 6
Что-то по строкам:
my $i = 0;
while ($i < scalar(@array)) {
if (ref @array[$i] eq 'ARRAY') {
splice @array, $i, 1, @$array[$i];
} else {
$i++;
}
}
Я написал это вслепую, понятия не имею, работает ли оно на самом деле, но вы должны получить эту идею.
Ответ 7
То же, что и решение Vijayender, но будет работать со смешанными массивами, содержащими arrayrefs и scalar.
$ref = [[1,2,3,4],[5,6,7,8],9,10];
@a = map { ref $_ eq "ARRAY" ? @$_ : $_ } @$ref;
print "@a"
Конечно, вы можете распространить его также на разыменование хеш-ссылок:
@a = map { ref $_ eq "ARRAY" ? @$_ : ref $_ eq "HASH" ? %$_: $_ } [email protected];
или используйте 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