perlstrawberry-perl

Dynamically Change the Key Value based on Delimiter in Perl


I'm reading from a CSV file and populating a Hash based on Key-Value Pairs. The First Column of the record is the key, and the rest of the record is the value. However, for some file I need to make first 2 columns as Key and the rest of the record is value. I have written it as below based on if loop by checking the number of Key Columns, but I wanted to know if there is any better way to do this?

use strict;
use warnings;

open my $fh, '<:encoding(utf8)', 'Sample.csv'
      or die "Couldn't open Sample.csv";
my %hash;     
my $KeyCols=2;
    while (<$fh>) {
        chomp;
        if ($KeyCols==1) {
        next unless /^(.*?),(.*)$/;
        $hash{$1} = $2;
        }
        elsif ($KeyCols==2) {
        next unless /^(.*?),(.*?),(.*)$/;
        $hash{$1.$2} = $3;
        }
    }

Solution

  • Here is one way to allow for any number of key columns (not just 1 or 2), but it uses split instead of a regex:

    use warnings;
    use strict;
    
    my %hash;     
    my $KeyCols = 2;
    while (<DATA>) {
        chomp;
        my @cols = split /,/, $_, $KeyCols+1;
        next unless @cols > $KeyCols;
        my $v = pop @cols;
        my $k = join '', @cols;
        $hash{$k} = $v;
    }
    
    __DATA__
    a,b,c,d,e,f
    q,w,e,r,t,y
    

    This is a self-contained code example.


    A big assumption is that your CSV file does not contain commas in the data itself. You should be using a CSV parser such as Text::CSV anyway.