in reply to performing operation on multiple items in an array

Keeping the data in CSV format in memory is odd. One would normally split it when the data is obtained. The cost will be quite noticeable with your current approach since you will have to split each record once for every @switches.

Whether you pre-split the data or not, I suggest avoiding your current approach and just looping through the data once.

use strict; use warnings; my %start_time; my %total_time; while (<DATA>) { # Or iterate through your array chomp; my ($time, $name, $state) = split /,/; # Or better: Text::CSV if ($state eq 'on') { if ($start_time{$name}) { warn("$name already on!\n"); next; } $start_time{$name} = $time; } else { if (!$start_time{$name}) { warn("$name not yet on!\n"); next; } $total_time{$name} += $time - delete $start_time{$name}; } } for my $name (sort keys %start_time) { warn("$name never turned off!\n"); } for my $name (sort keys %total_time) { print("$name was on for $total_time{$name} seconds\n"); } __DATA__ 10000,switchA,on 10001,switchB,on 10002,switchC,on 10005,switchA,off 10007,switchA,on 10012,switchC,off 10013,switchB,off 10015,switchA,off 10020,switchE,on 10020,switchD,off 10020,switchF,on 10021,switchF,on

If you only want the info for some switches, just add a check:

... my %switches = map { $_ => 1} @switches; while (<DATA>) { chomp; my ($time, $name, $state) = split /,/; next if !$switches{$name}; ... } ...

Replies are listed 'Best First'.
Re^2: performing operation on multiple items in an array
by ww (Archbishop) on Apr 11, 2008 at 13:04 UTC

    Extending ikegami's (++) to account for vatheck's multi-state lightswitch ("there are multiple possible states of off and one possible state of on") by adding a "switching" state as one of the possible states defined -- quite arbitrarily and sometimes illogically -- as "off":

    #!/usr/bin/perl use strict; use warnings; my %start_time; my %total_time; while (<DATA>) { # Or iterate through your array chomp; my ($time, $name, $state) = split /,/; # Or better: Text::CSV if ($state eq 'on') { if ($start_time{$name}) { warn("$name already on at $time!\n"); next; } $start_time{$name} = $time; } elsif ($state eq 'switching') { if (!$start_time{$name}) { warn("$name changing state at $time!\n"); next; } } else { if (!$start_time{$name}) { warn("$name not yet on at $time\n"); next; } $total_time{$name} += $time - delete $start_time{$name}; } } for my $name (sort keys %start_time) { warn("$name never turned off!\n"); } for my $name (sort keys %total_time) { print("$name was on for $total_time{$name} seconds\n"); } __DATA__ 10000,switchA,on 10001,switchB,on 10002,switchC,on 10005,switchA,off 10007,switchA,on 10012,switchC,off 10013,switchB,off 10015,switchA,off 10020,switchE,on 10020,switchD,off 10020,switchF,on 10021,switchF,on 10099,switchZ,switching 10100,switchZ,on 10101,switchZ,off 10089,switchY,on 10093,switchY,switching 10094,switchY,off

    Produces:

    switchD not yet on at 10020 switchF already on at 10021! switchZ changing state at 10099! switchE never turned off! switchF never turned off! switchA was on for 13 seconds switchB was on for 12 seconds switchC was on for 10 seconds switchY was on for 5 seconds switchZ was on for 1 seconds

      :-) This does make this binary-minded pilgrim wonder though: "Is vatheck controlling a "3-way" bulb?"

    More seriously, depending on the nature of the auditing being done, it might be well to calculate the "on" duration (as of the time of reporting) for those switches which are "never turned off" by subtracting the time of their first appearance in the data, to the last time found for any switch.

      I just wanted to update that this did work for me after a few minor modifications. Mostly just taking out the warnings because the boss only wanted to see the downtimes in a text file with no other noise. thank both of you for the help.