0

I am very new to Perl. I have read in a file and separated it into columns or "fields". The file has several columns, but only 5 specific columns needed to keep track of (call them A-E). In each field is some type of request (Get, Update, etc.). I am trying to read in the request types and count how many of each type there are, but I am having trouble separating each specific value. What is the best way to push just the single, unique request values into an array (without repeating), and count the occurrences as well?

The file input looks something like this.

65739483|test|Add|54758|Update|1443|Add|||||testing||||...
65739483|test|Delete|54758|Add|1443|Get|||||test2||||...

This is what I have so far.

....
My @fields = split(/\|/, $line);
my $a_column = $fields [2];
my $b_column = $fields [4];
my $c_column = $fields [6];
my $d_column = $fields [8];
my $e_column = $fields [10];

my @request_types = ();

foreach my $new_request ($a_column) {
    if($new_request && $new_request !~ @request_types) {
        push(@request_types, "$new_request");
    }
}
....

When I run this it prints out the entire column, something like this.

Add Delete Delete Update Add ...

I have been trying nested for loops, 2d matrices, etc. and cannot seem to get it to work. Is there a much simpler way to approach this that I am missing? Dictionaries maybe?

3
  • Welcome to StackOverflow. Please edit your post and include a representative sample of the input data, and explain what you mean by "cannot seem to get it to work". Show the expected output, the actual output and what steps you've taken to identify the problem. Commented Dec 11, 2018 at 1:22
  • You just want the total number of each Add, Delete, etc. in all of those columns combined? Commented Dec 11, 2018 at 2:25
  • Yes! I assumed some sort of dictionary would work for this, considering you can use the unique keys as the request types and the values as the counts, but could not for the life of me get it to work. Commented Dec 11, 2018 at 2:29

1 Answer 1

1

You're on the right track about wanting to use a hash table to keep track of the request types, not an array:

#!/usr/bin/perl
use warnings;
use strict;
use feature qw/say/;

my %requests;

while (<>) {
  chomp;
  my @fields = split /\|/;
  # Increment the count based on the values in these indexes of the array
  $requests{$_} += 1 for @fields[2,4,6,8,10];
}

say "$_: $requests{$_}" for sort keys %requests;

The above uses an array slice to get all the relevant values from the @fields array without using a bunch of extra variables, and then loops over them, incrementing entries in a hash table. Then it loops again over the keys in that table to display the results.

Sign up to request clarification or add additional context in comments.

3 Comments

$requests{$_} += 1 is better written as ++$requests{$_};
@ikegami I don't like to use increment/decrement operators unless actually taking advantage of their side-effects (Which is almost never the case)
Backwards. If you used ++$requests{$_};, you would be taking advantage of its side effect, but you wouldn't be taking advantage of the value it returns. The thing is, this is EXACTLY what you are doing now. You are only using $requests{$_} += 1; for its side-effect, ignoring the value it returns. $requests{$_} += 1 and ++$requests{$_} even return exactly the same value! $requests{$_} += 1 is purely a slow and weird version of ++$requests{$_}.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.