2016-05-19 2 views
0

У меня есть два массива,Match массив на основе существующего массива

my @test = ('a','b','c','d','e',f,'g','h'); 

my @test2 = ('h','b','d'); 

Я пытаюсь Переберите массива @test и спичечных элементов против тех, в @test2, удаление тех элементов, которые не существуют.

У меня есть следующий код:

foreach my $header (@test) { 
     if(exists $test2[$header]){ 
      # do nothing 
     } 
     else { 
      delete $test[$header]; 
     } 
    } 

Итак, я хочу, чтобы массив @test выглядеть следующим образом (игнорировать тот факт, это может быть отсортирован в алфавитном порядке):

my @test = ('b','d','h'); 

Однако в настоящее время мой массив остается неизменным после цикла foreach, может ли кто-нибудь предположить, почему?

ответ

2

Вы недопонимаете, для чего установлен заголовок. Он задан (псевдоним) значение в массиве.

Так

foreach my $header (@test) { 
    print $header,"\n"; 
} 

Даст вам a, b, c и т.д.

Однако, вы пытаетесь получить доступ $test2['a'] который не является действительным, так как оно должно быть числовым.

Так на самом деле, хороший пример в том, почему вы должны использовать strict и warnings, потому что это сказали бы вам проблему:

Argument "a" isn't numeric in array or hash lookup at 
Argument "b" isn't numeric in array or hash lookup at 

т.д.

Так что ничего не на самом деле делать.

Вы не должны использовать удаление таким образом, хотя, потому что вы удаляете из списка, итерации его. Это нехорошо, даже без того факта, что абсурдно использовать букву в качестве индекса массива.

Вы могли бы это сделать, как это вместо того, чтобы хотя:

#!/usr/bin/env perl 
use strict; 
use warnings; 
use Data::Dumper; 

my @test = ('a','b','c','d','e','f','g','h'); 

my @test2 = ('h','b','d'); 

my %is_in_test2 = map { $_ => 1 } @test2; 
@test = grep { $is_in_test2{$_} } @test; 

print Dumper \@test; 

Если вы хотите перебрать по индексу, вы можете сделать это следующим образом:

for my $index (0..$#test) { 
    print "$index => $test[$index]\n"; 
} 

Но я бы все-таки предположить, что удаление в то время как итерация не является отличным планом, потому что изменение того, что вы повторяете (и для изменения размера массива), - это хороший способ получить странные ошибки.

Так, пока вы можете:

for my $index (0..$#test) { 
    print "$index => $test[$index]\n"; 
    delete $test[$index] if not $is_in_test2{$test[$index]}; 
} 
print Dumper \@test; 

Что вы будете в конечном итоге с является:

$VAR1 = [ 
      undef, 
      'b', 
      undef, 
      'd', 
      undef, 
      undef, 
      undef, 
      'h' 
     ]; 

Для более общем случае аа FAQ: How do I computer the difference/intersection of two arrays

+0

oh спасибо, как я могу получить доступ к стоимости из интереса? –

+0

Значения индекса? Обычно 'for my $ index (0 .. $ # test) {' – Sobrique

0
use strict; 
use warnings; 


my @test = ('a','b','c','d','e','f','g','h'); 
my @test2 = ('h','b','d'); 

foreach my $header (@test) { 
    foreach my $header2 (@test2) { 
     if($header eq $header2) { 
      print "$header,";  #prints only existing values 
     } 
     else { 
      #doNothing 
     } 
    } 
} 

Примечание : Этот метод невозможен, когда вы имеете дело с массивом с огромными элементами.

+0

Это алгоритм O (N^2), так что да. Как массивные агитации, это будет медленным. – Sobrique

Смежные вопросы