1

I have an array in which I want to check if the element in the following check returns a certain value, remove it from the array if matches condition. Continue looping trough array, until all elements are gone.

foreach $temp (@inputs);
    {
        my $check = &checkStatus($temp, $server);
        if ($check ne "Z");
        print "$temp failed!\n";
    }
Alexander Farber
  • 21,519
  • 75
  • 241
  • 416

3 Answers3

1

It would be best if you had a way to wait for the status of any of the items to change.

For example, if you were dealing with processes, you could use.

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"); }
}

Otherwise, you will need to poll.

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.
}

Note that in both cases, you can use the value of the hash elements to contain information about the thing.

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

 # When waiting the foos.
 my $foo = delete($foos{$foo_id});
ikegami
  • 367,544
  • 15
  • 269
  • 518
1

You can use grep, as suggested by @Shawn:

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

Here, grep evaluates the last expression supplied to it, which is whether checkStatus(...) returns non-Z. By default, each element of the @inputs array is assigned to $_ inside. grep returns all elements of the array for which the condition is true.

Note that it is not necessary to use & before the method call here, because you are using parenthesis. See perlsub for details, and also explained by @ikegami here.

Timur Shtatland
  • 12,024
  • 2
  • 30
  • 47
0

Oleg, the description of the problem is not very clear.

Your code does not delete anything from array. I assume that you want to iterate through array and only print data when element meets some condition.

Please see the following example where I imitate in an array storing temperature reported by farm of servers

#!/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

Output

♿ server3 temp=42
♿ server5 temp=37
Polar Bear
  • 6,762
  • 1
  • 5
  • 12