Perl цикл массива - PullRequest
       9

Perl цикл массива

1 голос
/ 06 февраля 2020

У меня есть массив, в котором я хочу проверить, возвращает ли элемент в следующей проверке определенное значение, удалите его из массива, если соответствует условию. Продолжайте циклический массив, пока все элементы не исчезнут.

foreach $temp (@inputs);
    {
        my $check = &checkStatus($temp, $server);
        if ($check ne "Z");
        print "$temp failed!\n";
    }

Ответы [ 3 ]

1 голос
/ 07 февраля 2020

Вы можете использовать grep, как предложено @Shawn:

@inputs_wo_z = grep { checkStatus($_, $server) ne "Z" } @inputs;

Здесь grep вычисляет последнее переданное ему выражение, а именно: checkStatus(...) возвращает не Z. По умолчанию каждому элементу массива @inputs назначается $_ внутри. grep возвращает все элементы массива, для которых выполняется условие.

Обратите внимание, что здесь нет необходимости использовать & перед вызовом метода, поскольку вы используете скобки. Подробнее см. perlsub, а также @ikegami здесь .

1 голос
/ 06 февраля 2020

Было бы лучше, если бы у вас была возможность дождаться изменения состояния любого из элементов.

Например, если вы имели дело с процессами, вы можете использовать.

my %children = map { $_ => 1 } @pids;

while (%children) {
   my $pid = wait();
   my $status = $?;

   delete($children{$pid});

   if    ( $status & 0x7F ) { warn("Child $pid killed by signal ".( $status & 0x7F )."\n"); }
   elsif ( $status >> 8   ) { warn("Child $pid exited with error ".( $status >> 8 )."\n"); }
   else                     { print("Child $pid exited successfully\n"); }
}

В противном случае вам потребуется опросить.

use Time::HiRes qw( sleep );  # Time::HiRes::sleep supports fractional durations.

my %foos = map { $_ => 1 } @foo_ids;

while (%foos) {
   for my $foo_id (keys(%foos)) {
      if (checkStatus($foo_id, $server) eq 'Z') {
         delete($foos{$foo_id});
         # ...?
      }
   }

   sleep(0.1);  # To avoid using 100% CPU.
}

Обратите внимание, что в обоих случаях вы можете использовать значение элементов ha sh, чтобы содержать информацию о предмете.

 # When creating the foos.
 $foos{$foo_id} = $foo;

 # When waiting the foos.
 my $foo = delete($foos{$foo_id});
0 голосов
/ 07 февраля 2020

Олег, описание проблемы не очень понятно.

Ваш код ничего не удаляет из массива. Я предполагаю, что вы хотите перебирать массив и печатать данные только тогда, когда элемент удовлетворяет некоторому условию.

Пожалуйста, посмотрите следующий пример, где я имитирую в массиве, хранящем температуру, сообщаемую фермой серверов

#!/usr/bin/perl -CS
#
# vim: ai:ts=4:sw=4
#

use strict;
use warnings;
use feature 'say';

my $max_temp = 36;      # maximum permited termperature

my @data = <DATA>;      # fill array with some data

for (@data) {
    next if /^\s*$/;        # skip empty lines

    chomp;
    my($s,$t) = split ',';

    say chr(0x267F) . " $s temp=$t" if $t > $max_temp;
}


__DATA__
server1,32
server2,30
server3,42
server4,32
server5,37
server6,36
server7,30

Выход

♿ server3 temp=42
♿ server5 temp=37
...