как со строкой: s#^\s+##; s#\s+$##; s#\s+# #g;
upd:
DB<2> p join",",map { defined($_)?$_:"undef" } @a
undef,undef,1,2,3,undef,undef,undef,4,undef,5,undef,undef,6,undef,undef
DB<3> my ($a,$b) = (0,0); map { defined($_) ? ($a++,$b=0) : ($b++&&splice@a,$a++,1) } @a
DB<4> defined($a[0])||splice@a,0,1
DB<5> defined($a[$#a])||splice@a,$#a,1
DB<6> p join",",map { defined($_)?$_:"undef" } @a
1,2,3,undef,4,undef,5,undef,6
upd:
map { defined($_) ? ($a++,$b=0) : ($b++?splice@_,$a,1:$a++); } @_;
no subject
Date: 2007-03-25 11:24 pm (UTC)sub clean_array{push@_,undef;defined$_[0]||defined$_[-1]?push@_,shift:shift for 1..@_;pop;@_}no subject
Date: 2007-03-25 11:39 pm (UTC)no subject
Date: 2007-07-13 07:36 pm (UTC)#!/usr/bin/perl use Benchmark qw(:all); my @a=((10)x10,(undef)x10)x10; cmpthese(32768, { clean_array1 => sub {clean_array1(@a)}, clean_array2 => sub {clean_array2(@a)}, clean_array3 => sub {clean_array3(@a)}, }); sub clean_array1{push@_,undef;defined$_[0]||defined$_[-1]?push@_,shift:shift for 1..@_;pop;@_} sub clean_array2 { my ($a,$b) = (0,0); map { defined($_) ? ($a++,$b=0) : ($b++?splice@_,$a,1:$a++); } @_; } sub clean_array3 { my $buff; grep { $buff ? ($buff=$_)||1 : ($buff=$_) } @_; }Кста, вторая делает что то чтранное вместо чистки.
no subject
Date: 2007-07-13 07:39 pm (UTC)no subject
Date: 2007-07-13 07:49 pm (UTC)no subject
Date: 2007-07-15 10:17 am (UTC)Однако, Ваш код при всей его быстроте задачу не решает :)
Во-первых, он не уважает нули. Вот такое он вычистит, в то время как по "условиям задачи" не надо бы:
my @a=((10)x10,(0)x10)x10;
Во вторых, он не отрезает последний undef элемент в массиве (это видно даже по Вашим тестам).
А если это исправить, например так:
sub clean_array4 { my $buff; $_ = [grep { defined($buff) ? ($buff=$_)||1 : defined($buff=$_) } @_, undef]; pop @$_; @$_; }- то работать это начинает уже не так фантастически быстро. Но, разумеется, быстрее первого варианта.
no subject
Date: 2007-07-15 04:54 pm (UTC)ну почистить начало и конец - это несложно.
про хвосты я просчто не думаю.
А вот [] - это как раз и есть путь к тормозам.
Вся фишка в том, что хэш и спифок - это базовые типы, и при их присваивании происходит копирование.
копирование - это опирация O(n) - и нам очень жадно, особенно при больших n.
Операция [@a] приводится к my @b=@a; return \@b;
Дописывание андефа в начало и конец - тоже операция над массивом, которая потом разворачивается в кол-во начальных+завершающих андефов.
лучше обрезать потом так:
pop || push; shift || unshift;
или соостветственно
defined($_=pop) || push; defined($_=shift) || unshift;
no subject
Date: 2007-07-17 06:23 pm (UTC)sub clean_array5 { my $buff; $_ = [grep { defined($buff) ? ($buff=$_)||1 : defined($buff=$_) } @_]; defined($buff = pop @$_) and push @$_, $buff; @$_; } sub clean_array6 { my $buff; @_ = grep { defined($buff) ? ($buff=$_)||1 : defined($buff=$_) } @_; defined($_ = pop @_) and push @_, $_; @_; }Вариант с [] работает на 33% быстрее.
А обрезание типа defined($_=pop) && push действительно выигрывает 1% скорости, если на конце есть undef, и работает примерно так же, если undef нет.