I have a program that at the moment reads from FILE 1 looking like the one below and matching certain characters. e.g
Type, Fruit, Description, quantity tropical, banana, tasty and yummy, 5 tropical, grapefruit, bitter and not yummy, 2 ... and so on
First of all I wanted to create hash of hashes for each 'Type', 'Fruit', 'Description', 'Quantity' and store the different values in the reference hashes. That works fine with the code below.
use strict;
use warnings;
use Data::Dumper;
use Text::CSV;
my %MacroA = ('Type' => {}, 'Fruit' => {}, 'Description' => {}, 'Quantity' => {});
open (my $file, '<', 'FRUITIES.txt') or die $!;
while (my $line = <$file>) {
if ($line =~ /\b(tropical)\b,/) {
$MacroA{Type}->{$1}++;
}
if ($line =~ /,\b(banana|grapefruit)\b,/) {
$MacroA{Fruit}->{$1}++;
}
if ($line =~ /,([\w\s]+?),/) {
$MacroA{Description}->{$1}++;
}
if ($line =~ /,([\d]+?)/) {
$MacroA{Quantity}->{$1}++;
}
}
close $file;
So my question is How can I put this data(data is not fixed) into a csv file or anything related(maybe xls), that would be a table with columns for each hash of hashes ('Type', 'Fruit', 'Description', 'Quantity').
To append a new value to the array of values associated with a particular key, use push : push @{ $hash{"a key"} }, $value; The classic application of these data structures is inverting a hash that has many keys with the same associated value. When inverted, you end up with a hash that has many values for the same key.
To read a column from csv for this purpose I wrote this script: #!/usr/bin/perl -w use strict; use warnings; use Text::CSV; my$column_separator = qr/,/; my $column_number = "3"; my$file = "/home/Admin/Documents/new (copy).
I agree that hashes of hashes is a good thing, but I think you're not storing it in a way you can retrieve it easily.
One way you could do it is like this.
{ id_1 => {
data_1 => "blah",
data_2 => "foo",
...
},
id_2 => {
...
},
...
}
First of all, you need to pick which column would be the "ID". This would determine the uniqueness of each ROW. Let's say for your example let's pick the fruit, since we're assuming there would be no two fruits that would appear in the same file. So we would have something like this:
{ banana => {
type => "tropical",
description => "tasty and yummy",
...
},
grapefruit => {
...
},
...
}
In order to change this back to CSV, we loop through the hashes.
my %fruit_data; #let's assume that this already has the data in it
foreach my $fruit ( keys %fruit_data ) {
#given the $fruit you can now access all the data you need
my $type = %fruit_data{$fruit}{'type'};
my $desc = %fruit_data{$fruit}{'description'};
# etc...
# then you may want to store them in a scalar in any order you want
my $row = "$field,$type,$desc etc.\n";
# then work your way from there
}
For writing Excel files - you could use Spreadsheet::WriteExcel.
About CSV files - originally you have the CSV-file with "," delimiter and "\n" string delimiters. If you want to write some array of hashrefs to CSV - better way to write down simple sub by yourself, smth like this one:
use strict;
use warnings;
sub write_csv {
my ($array_ref, $fh) = @_;
for my $row (@$array_ref) {
print $fh join(',', map { $_, $row->{$_} } sort keys %$row), "\n";
}
}
my $test = [
{a => 1, ab => 2, type => '234k', count => '123'},
{a => 3, ab => 2, type => 'some_type', count => 34},
];
open my $fh, '>', 'test.csv' or die $!;
write_csv($test, $fh);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With