http://www.perlmonks.org?node_id=995152


in reply to counting elements using a hash

The first task is to get the "number" that you wish to track from the input lines.

The second step is simply to count using a hash table. It is not necessary to test for exists(). Perl will create a new key if the key doesn't exist.

#!/usr/bin/perl -w use strict; my %count; open (INPUT, '<', "some_input_file") or die "unable to open some_input_file"); while (<INPUT>) { my ($number) =~ /(\d+)/; #maybe???? next unless $number; #skip undef's $count{$number}++; #new key if $number not there } foreach my $number (sort{$a <=> $b} keys %count) #numeric sort { print "$number occurs $count{$number} time(s)\n"; }
Try again and show some just a couple of lines of example input and your revised code.

There is no need to iterate over all 101 possibilities for the number on each line. Process each line once, get the number, make a decision and it is "over with" - don't loop 100 times for each input line.

Replies are listed 'Best First'.
Re^2: counting elements using a hash
by AnomalousMonk (Archbishop) on Sep 23, 2012 at 09:08 UTC
        next unless $number; #skip undef's

    What happens if the extracted  $number string is '0'? Will zeros be counted?

      That is a good point. These zero's or undef's are problematic.

      The problem statement had 1..100 so this zero didn't enter into the situation. In this case, $number==0 should be skipped (same as undef). So what about $number >100? Well, the OP should should show some revised code and we will iterate again to get it fine tuned. A major point was that Perl will create a new key (auto-vivify) when needed - there is no need to test whether or not the key exists. Second point was a numeric instead of alpha sort.

Re^2: counting elements using a hash
by bk1388 (Initiate) on Sep 23, 2012 at 21:13 UTC

    here is my revised code and it's working like a charm I the file contains only numbers (integers and decimals), no zeros, thank you all for your input

    my $INPUT_FILE; my $OUTPUT_FILE; my %count; open ($INPUT_FILE, "< " ) or die "Can't open file"; open ($OUTPUT_FILE, ">output") or die "can't open output file"; while($number = readline($INPUT_FILE)){ $count{$number}++; } foreach $number(sort keys %count){ print "$number occurs $count{$number} times(s)\n"; } close ($OUTPUT_FILE) or die "Can't close file!!!";