in reply to Re: another 'array to hash' question
in thread another 'array to hash' question

well, the simplest use of what I am looking for would be in converting a csv or tab delim var file into an array of hashes...

my @a; while (<INFILE>) { my ($fn, $ln, $age) = split("\t", $_); # now convert this array to a hash and stuff it in the array push(@a, {'fn'=>$fn, 'ln'=>$ln, 'age'=>$age}); }

DBI returns a nicely prepared array of hashes with fetchall_arrayref({}) and I was trying to "emulate" that while using text files. But, "if I could", I would probably find other uses as well.

Replies are listed 'Best First'.
Re: Re: Re: another 'array to hash' question
by stajich (Chaplain) on Dec 10, 2003 at 15:40 UTC
    Does the CSV have a header line which describes the columns? I often do this
    chomp($headerline = <INFILE>); my @header = split(/\t/,$headerline);
    (although you could just define one relative to the code
    my @header = qw(fn ln age);
    Now when reading in the file
    while( <INFILE>) { chomp; my $c = 0; my @columns = split(/\t/,$_); push @a, { map { $header[$c++] => $_ } @columns }; }
      That's what I would have suggested, with one change: use a hash slice.
      # instead of this my $c = 0; my @columns = split(/\t/,$_); push @a, { map { $header[$c++] => $_ } @columns }; # do this my %row; @row{@header} = split(/\t/,$_); push @a, \%row;
      They're functionally equivalent, I know... but it's just that since what you are doing is really a hash-slice, why not use hash-slice syntax?

      ------------
      :Wq
      Not an editor command: Wq
Re: Re: Re: another 'array to hash' question
by allolex (Curate) on Dec 10, 2003 at 15:15 UTC

    I really don't see why you shouldn't do it the way you have it coded here. And since you probably already know what the fields are, you can even skip the hash altogether. An array of arrays looks good to me.

    my @a; while (<INFILE>) { my @line = split /\t/; push @a, \@line; # Array of array references }

    Or even:

    my @a; push @a, ( split /\t/ ) while (<INFILE>); # array of arrays

    which provides a nice list context to put your input directly into an array. :)

    --
    Allolex

      >And since you probably already know what the fields are,
      >you can even skip the hash altogether. An array of arrays
      >looks good to me

      unfortunately, I need an array of hashes ;-). The best use is to just stick a ref to that array inside a tmpl_loop in HTML::Template. Besides, an aOfH is more intuitive for me. That said...

      >I really don't see why you shouldn't do it the way you have it
      >coded here.

      because, one, I might not know what the variable names are (they may be variables... as alluded to below), and two, it just gets tiring typing out a hash structure especially if a lot of fields are involved. Tom's suggestion below works well for such a problem.

      Thanks though for you help.

        I really don't see why you shouldn't do it the way you have it coded here.
        because, one, I might not know what the variable names are (they may be variables... as alluded to below), and two, it just gets tiring typing out a hash structure especially if a lot of fields are involved. Tom's suggestion below works well for such a problem.

        Why are the variable names important if you know what each column represents? A hash structure is indeed useful for HTML::Template so you can refer to that data by name in the template, which is, for most people's purposes, completely separate from the code. (In templates there is no guarantee that the person editing the template will know anything about structures in the code.) But with the AofA, you know that $crazypersonarray->[0] is a lastname *variable* and so on. You could even assign $ln = 0 and refer to it as $crazypersonarray->[$ln]. Your array of hashes can be accessed using something like print $hash->{ln} for my $hash ( @aoh );. That said, I think you should use what feels intuitively "right". :)

        --
        Allolex