Каков наилучший способ удалить значение из массива в Perl? - PullRequest
76 голосов
/ 06 октября 2008

В массиве много данных, и мне нужно удалить два элемента.

Ниже приведен фрагмент кода, который я использую,

my @array = (1,2,3,4,5,5,6,5,4,9);
my $element_omitted = 5;
@array = grep { $_ != $element_omitted } @array;

Ответы [ 13 ]

1 голос
/ 15 февраля 2019

Просто чтобы убедиться, что я протестировал решения grep и map, сначала выполняя поиск индексов соответствующих элементов (удаляемых), а затем непосредственно удаляя элементы с помощью grep без поиска индексов. Похоже, что первое решение, предложенное Сэмом при задании его вопроса, было уже самым быстрым.

    use Benchmark;
    my @A=qw(A B C A D E A F G H A I J K L A M N);
    my @M1; my @G; my @M2;
    my @Ashrunk;
    timethese( 1000000, {
      'map1' => sub {
          my $i=0;
          @M1 = map { $i++; $_ eq 'A' ? $i-1 : ();} @A;
      },
      'map2' => sub {
          my $i=0;
          @M2 = map { $A[$_] eq 'A' ? $_ : () ;} 0..$#A;
      },
      'grep' => sub {
          @G = grep { $A[$_] eq 'A' } 0..$#A;
      },
      'grem' => sub {
          @Ashrunk = grep { $_ ne 'A' } @A;
      },
    });

Результат:

Benchmark: timing 1000000 iterations of grem, grep, map1, map2...
  grem:  4 wallclock secs ( 3.37 usr +  0.00 sys =  3.37 CPU) @ 296823.98/s (n=1000000)
  grep:  3 wallclock secs ( 2.95 usr +  0.00 sys =  2.95 CPU) @ 339213.03/s (n=1000000)
  map1:  4 wallclock secs ( 4.01 usr +  0.00 sys =  4.01 CPU) @ 249438.76/s (n=1000000)
  map2:  2 wallclock secs ( 3.67 usr +  0.00 sys =  3.67 CPU) @ 272702.48/s (n=1000000)
M1 = 0 3 6 10 15
M2 = 0 3 6 10 15
G = 0 3 6 10 15
Ashrunk = B C D E F G H I J K L M N

Как показывают прошедшие времена, бесполезно пытаться реализовать удаление функция, использующая либо grep, либо карту определенных индексов. Просто grep-удалить напрямую.

До тестирования я думал, что "map1" будет наиболее эффективным ... Я должен чаще полагаться на Benchmark, я думаю. ; -)

0 голосов
/ 13 марта 2013

Аналогичный код, который я однажды написал, чтобы удалить строки, не начинающиеся с SB.1, из массива строк

my @adoSymbols=('SB.1000','RT.10000','PC.10000');
##Remove items from an array from backward
for(my $i=$#adoSymbols;$i>=0;$i--) {  
    unless ($adoSymbols[$i] =~ m/^SB\.1/) {splice(@adoSymbols,$i,1);}
}
0 голосов
/ 06 октября 2008

Если вы знаете индекс массива, вы можете удалить () его. Разница между splice () и delete () заключается в том, что delete () не перенумеровывает остальные элементы массива.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...