Если вам не нравится боль, используйте Text::CSV
и его родственников Text::CSV_XS
и Text::CSV_PP
.
Однако, это может быть более легкой частью этой проблемы. После того, как вы прочитали и проверили, что строка заполнена, вам необходимо добавить соответствующую информацию в правильно хешированные ключи. Возможно, вам также придется довольно близко ознакомиться со ссылками.
Возможно, вы создадите хеш %BranchData
с ключом ветви. Каждый элемент этого хеша будет ссылкой на хеш, заданный заданием; и каждый элемент в нем будет ссылаться на хеш, заданный timePeriod, и каждый элемент в нем будет ссылаться на массив с ключом по номеру дня (с использованием индексов 1..7; он немного выделяет пространство, но шансы получить это верно намного больше, хотя не связывайтесь с $[
!). И каждый элемент массива будет ссылкой на хеш, заданный тремя типами периодов. Ой!
Если все работает хорошо, типовое задание может выглядеть примерно так:
$BranchData{$row{branch}}->{$row{job}}->{$row{period}}->[1]->{$row{p_type}} +=
$row{day1};
Вы бы перебирали элементы 1..7 и 'day1' .. 'day7'; там нужно немного поработать над проектной работой.
Вам нужно беспокоиться о правильной инициализации (или, возможно, нет - Perl сделает это за вас). Я предполагаю, что строка возвращается как прямой хэш (а не ссылка на хеш) с ключами для ветви, задания, периода, типа периода (p_type
) и каждого дня ('day1', .. 'day7 «).
Если вы знаете, какой день вам нужен заранее, вы можете избежать накопления всех дней, но это может сделать более общую отчетность проще для чтения и накопления всех данных все время, а затем просто иметь дело с печатью с любым подмножеством все данные должны быть обработаны.
Было достаточно интригующей проблемой, что я взломал этот код. Я сомневаюсь, что это оптимально, но это работает.
#!/usr/bin/env perl
#
# SO 8570488
use strict;
use warnings;
use Text::CSV;
use Data::Dumper;
use constant debug => 0;
my $file = "input.csv";
my $csv = Text::CSV->new({ binary => 1, eol => $/ })
or die "Cannot use CSV: ".Text::CSV->error_diag();
my @headings = qw( branch job period p_type day1 day2 day3 day4 day5 day6 day7 );
my @days = qw( day0 day1 day2 day3 day4 day5 day6 day7 );
my %BranchData;
open my $in, '<', $file or die "Unable to open $file for reading ($!)";
$csv->column_names(@headings);
while (my $row = $csv->getline_hr($in))
{
print Dumper($row) if debug;
my %r = %$row; # Not for efficiency; for notational compactness
$BranchData{$r{branch}} = { } if !defined $BranchData{$r{branch}};
my $branch = $BranchData{$r{branch}};
$branch->{$r{job}} = { } if !defined $branch->{$r{job}};
my $job = $branch->{$r{job}};
$job->{$r{period}} = [ ] if !defined $job->{$r{period}};
my $period = $job->{$r{period}};
for my $day (1..7)
{
# Assume that Overtime, Regular and Variance are the only types
# Otherwise, you need yet another level of checking whether elements exist...
$period->[$day] = { Overtime => 0, Regular => 0, Variance => 0} if !defined $period->[$day];
$period->[$day]->{$r{p_type}} += $r{$days[$day]};
}
}
print Dumper(\%BranchData);
Учитывая ваши данные выборки, вывод из этого:
$VAR1 = {
'West' => {
'Electrician' => {
'12PM-5PM' => [
undef,
{
'Regular' => '4.25',
'Overtime' => 0,
'Variance' => 0
},
{
'Regular' => 0,
'Overtime' => 0,
'Variance' => 0
},
{
'Regular' => 0,
'Overtime' => 0,
'Variance' => 0
},
{
'Regular' => '-1.25',
'Overtime' => 0,
'Variance' => 0
},
{
'Regular' => '-1.5',
'Overtime' => 0,
'Variance' => 0
},
{
'Regular' => '-1.5',
'Overtime' => 0,
'Variance' => 0
},
{
'Regular' => 0,
'Overtime' => 0,
'Variance' => 0
}
]
}
},
'South' => {
'Manager' => {
'12A-9AM' => [
undef,
{
'Regular' => 0,
'Overtime' => '77.75',
'Variance' => 0
},
{
'Regular' => 0,
'Overtime' => '14.75',
'Variance' => 0
},
{
'Regular' => 0,
'Overtime' => 10,
'Variance' => 0
},
{
'Regular' => 0,
'Overtime' => 10,
'Variance' => 0
},
{
'Regular' => 0,
'Overtime' => 10,
'Variance' => 0
},
{
'Regular' => 0,
'Overtime' => 10,
'Variance' => 0
},
{
'Regular' => 0,
'Overtime' => 10,
'Variance' => 0
}
]
}
},
'North' => {
'Janitor' => {
'5PM-12AM' => [
undef,
{
'Regular' => 0,
'Overtime' => 0,
'Variance' => '-4.25'
},
{
'Regular' => 0,
'Overtime' => 0,
'Variance' => 0
},
{
'Regular' => 0,
'Overtime' => 0,
'Variance' => 0
},
{
'Regular' => 0,
'Overtime' => 0,
'Variance' => '-1.25'
},
{
'Regular' => 0,
'Overtime' => 0,
'Variance' => '-1.5'
},
{
'Regular' => 0,
'Overtime' => 0,
'Variance' => '-1.5'
},
{
'Regular' => 0,
'Overtime' => 0,
'Variance' => 0
}
]
}
},
'East' => {
'Banker' => {
'9AM-12PM' => [
undef,
{
'Regular' => 0,
'Overtime' => '4.25',
'Variance' => 0
},
{
'Regular' => 0,
'Overtime' => 0,
'Variance' => 0
},
{
'Regular' => 0,
'Overtime' => 0,
'Variance' => 0
},
{
'Regular' => 0,
'Overtime' => '1.25',
'Variance' => 0
},
{
'Regular' => 0,
'Overtime' => '1.5',
'Variance' => 0
},
{
'Regular' => 0,
'Overtime' => '1.5',
'Variance' => 0
},
{
'Regular' => 0,
'Overtime' => 0,
'Variance' => 0
}
]
}
}
};
Получите удовольствие, забрав его отсюда!