Если вы можете использовать Text :: CSV_XS, как показывает Шон , сделайте это.
У нас есть упражнение Средний Perl, которое делает это. Используйте первую строку, чтобы сопоставить имена заголовков с позицией, а затем используйте это ha sh, чтобы перевести другой путь. Вот он с интенсивным использованием разыменования постфикса :
use v5.24;
my $data = [
[ 'id', 'name', 'value' ],
[ 23, 'foo', 77 ],
[ 44, 'bar', 'dfd' ],
];
# ikegami's suggestion
my %name_to_index = map { $data->[0][$i] => $_ } 0..$data->[0]->$#*;
foreach my $i ( 1 .. $data->$#* ) {
say $data->[$i][ $name_to_index{name} ]
}
Вот версия с оберткой, которая работает с версиями до v5.24, но я думаю, что это уродливее (и вы должны использовать шестилетний, без поддержки Perl):
use v5.10;
my $data = [
[ 'id', 'name', 'value' ],
[ 23, 'foo', 77 ],
[ 44, 'bar', 'dfd' ],
];
# ikegami's suggestion
my %name_to_index = map { $data->[0][$i] => $_ } 0.. $#{ $data->[0] };
foreach my $i ( 1 .. $#{ $data } ) {
say $data->[$i][ $name_to_index{name} ]
}
Поскольку реальный код, вероятно, намного сложнее, я думаю, что часто легче понять, когда вы не углубляетесь в структуру данных повсюду. Если вы не возражаете против дополнительной работы (как в жарком l oop), вы можете превратить ваш ряд в ха sh, где ключи - это заголовки (аналогично тому, что делает Text::CSV_XS
), и сыграть с этим ха sh, не задумываясь о всей цепочке разыменований. В этом примере используется фрагмент ha sh, чтобы заполнить все сразу. После этого вы играете с %hash
вместо $data->[$i][...]
:
use v5.24;
my $data = [
[ 'id', 'name', 'value' ],
[ 23, 'foo', 77 ],
[ 44, 'bar', 'dfd' ],
];
my @headers = $data->[0]->@*;
foreach my $i ( 1 .. $data->$#* ) {
my %hash;
@hash{ @headers } = $data->[$i]->@*;
say $hash{name};
}
Любопытно, что сразу после раздела Pseudoha sh в perlref , документы показывают пример с шаблонами функций , Вместо ha sh для сопоставления вы можете определить подпрограммы. Некоторым людям нравится, что имя индекса заголовка выглядит немного чище, но я не думаю, что это стоит дополнительного объяснения мягкого нарушения refs
и объяснения типов globs:
use v5.24;
my $data = [
[ 'id', 'name', 'value' ],
[ 23, 'foo', 77 ],
[ 44, 'bar', 'dfd' ],
];
foreach my $name ( $data->[0]->@* ) {
state $n = 0;
my $m = $n++; # don't reference $n
no strict 'refs'; # Hey there!
*{uc $name} = sub () { $m }; # runtime sub definition
}
foreach my $i ( 1 .. $data->$#* ) {
say $data->[$i][ NAME() ]
}