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}; ... } ...
In reply to Re: performing operation on multiple items in an array
by ikegami
in thread performing operation on multiple items in an array
by vatheck
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |