Извините, вам не очень понятно, что вы пытаетесь сделать и что означает "ссылка".Если я неправильно понял вашу проблему, пожалуйста, оцените и уточните.
Прежде всего, я бы настоятельно рекомендовал не использовать переменную names для структурирования данных (например, $ref_1_x
для хранения координаты x).для первой строки с меткой «ref»).
Если вы хотите сохранить координаты x, y и z, вы можете сделать это как массив из 3 элементов, почти так же, как вы сделали - единственное отличие состоит в том, чточто вы хотите сохранить массив ссылка (вы не можете сохранить массив как значение в другом массиве в Perl):
my ($first_column, @data) = split(/ +/, $line); # Remove first "ref" column
@coordinates[$count++] = \@data; # Store the reference to coordinate array
Затем, чтобы получить доступ к координате х для строки2, вы делаете:
$coordinates[1]->[0]; # index 1 for row 2; then sub-index 0 for x coordinate.
Если вы настаиваете на сохранении 3-х координат в именованной структуре данных, потому что sub-index 0 for x coordinate
выглядит менее читабельным - что является действительной проблемой в целом, но на самом деле не является проблемойс 3 столбцами - используйте хеш вместо массива:
my ($first_column, @data) = split(/ +/, $line); # Remove first "ref" column
@coordinates[$count++] = { x => $data[0], y => $data[1], z => $data[2] };
# curly braces - {} - to store hash reference again
Затем, чтобы получить доступ к координате х для строки 2, вы делаете:
$coordinates[1]->{x}; # index 1 for row 2
Теперь, если выТАКЖЕ хочу хранить строки, которые имеют значение первого столбцаf "в отдельной структуре данных, помеченной" ref ", вы можете сделать это, обернув исходный массив @coordinates
в значение в хэше с ключом" ref ".
my ($label, @data) = split(/ +/, $line); # Save first "ref" label
$coordinates{$label} ||= []; # Assign an empty array ref
#if we did not create the array for a given label yet.
push @{ $coordinates{$label} }, { x => $data[0], y => $data[1], z => $data[2] };
# Since we don't want to bother counting per individual label,
# Simply push the coordinate hash at the end of appropriate array.
# Since coordinate array is stored as an array reference,
# we must dereference for push() to work using @{ MY_ARRAY_REF } syntax
Затем, чтобы получить доступ к координате x для строки 2 для метки «ref», выполните:
$label = "ref";
$coordinates{$label}->[1]->{x}; # index 1 for row 2 for $label
Кроме того, в исходном коде примера есть пара устаревших идиом, которыеВы можете писать в лучшем стиле (используйте форму с тремя аргументами open()
, проверьте ошибки операций ввода-вывода, например open()
; используйте лексические дескрипторы файлов; сохраняйте весь файл в большом массиве вместо чтения построчно),
Вот слегка измененная версия:
use strict;
my %coordinates;
print "Loading file ...";
open (my $file, "<", "somefile.txt") || die "Can't read file somefile.txt: $!";
while (<$file>) {
chomp;
my ($label, @data) = split(/ +/); # Splitting $_ where while puts next line
$coordinates{$label} ||= []; # Assign empty array ref if not yet assigned
push @{ $coordinates{$label} }
, { x => $data[0], y => $data[1], z => $data[2] };
}
close($file);
print "Done!\n";
Не ясно, с чем вы хотите сравнить, с чем, поэтому не могу посоветовать это без дополнительных разъяснений.