Perl читать данные из текстового файла

Я хотел получить фрукты и информацию из входного файла по порядку (чтение с первой строки и далее). Приведенный ниже код каким-то образом печатает фрукты и информацию в любом случайном порядке, каждый раз при запуске скрипта генерируется другой порядок, а не чтение с первой строки. Любая рекомендация?

У меня есть входной файл, как показано ниже

apple
    text1
    text2
grape
    text3
    text4
jackfruit
    text5

и это код, который я должен вызывать каждый фрукт и информацию

use strict;
use warnings;


my %hash;

open FILE, "config.txt" or die $!;
my $key;
while (my $line = <FILE>) {
     chomp($line);
     if ($line !~ /^\s/) {
        $key = $line;
        #$hash{$key} = [];
     } else {
        $line =~ s/\s//g;
        push (@{ $hash{$key} }, $line);
     }

 }
close FILE;

my %final;
foreach my $fruit (keys %hash){
   foreach my $info (values @{$hash{$fruit}}){

    print "Fruit: $fruit\n";
    print "Info for $fruit = $info\n";


}
}
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
0
61
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий
keys %hash

Дает вам массив ключей из хэша, но не отсортированный. Вы можете отсортировать его с помощью команды sort

Вся линия будет

foreach my $fruit (sort(keys %hash)){

Используйте perldoc -f sort, чтобы получить помощь по функции сортировки.

Это работает только потому, что имена фруктов в примере уже отсортированы по алфавиту, поэтому сортировка хэша по алфавиту дает порядок файлов. Если фрукты в файле не в алфавитном порядке, этот метод не работает.

brian d foy 20.02.2023 10:46
print join(" ",sort(keys %{{2 => 3, 1 => 3, 0 => 6}})); дает 0 1 2. Для меня я выгляжу правильно
Oliver Gaida 20.02.2023 10:53

Я думаю, это зависит от того, какой порядок вы хотите. Теперь попробуйте с ключами 1, 11, 101, 2, 22, and 9`. Но я говорил о том порядке, в котором они появляются в файле, о чем и спрашивал ОП. Хэш этого не делает.

brian d foy 20.02.2023 10:58

хорошо, вы имеете в виду численную сортировку print join(" ",sort { $a <=> $b}(keys %{{1 => 3, 11 => 3, 101 => 6, 2 => 1, 22 => 1, 9 => 23 }})); дает 1 2 9 11 22 101

Oliver Gaida 20.02.2023 11:11

Неа. Я имею в виду вообще не сортировать. Сохраняйте порядок, как показано в файле.

brian d foy 20.02.2023 22:19

Спасибо, я действительно неправильно понял... омг.

Oliver Gaida 21.02.2023 06:40

Давайте продолжим обсуждение в чате.

Oliver Gaida 21.02.2023 06:54

Если вы хотите сохранить порядок вещей в файле, используйте массив. Каждый элемент этого массива может быть хешем, который упорядочивает данные:

#!perl

use v5.26;

my @items;
while( <DATA> ) {
    chomp;

    if ( /\A(\S+)/ ) {
        push @items, { fruit => $1, info => [] }
        }
    elsif ( /\A\s+(.+)/ ) {
        push $items[-1]{info}->@*, $1
        }
    }

foreach my $item ( @items ) {
    print "Fruit: $item->{fruit}\n";
    foreach my $info ( $item->{info}->@* ) {
        print "\tInfo: $info\n";
        }
    }

__END__
apple
    text1
    text2
grape
    text3
    text4
jackfruit
    text5
cranberry
    text6

Вывод поддерживает порядок в файле:

Fruit: apple
    Info: text1
    Info: text2
Fruit: grape
    Info: text3
    Info: text4
Fruit: jackfruit
    Info: text5
Fruit: cranberry
    Info: text6

Однако, если вы хотите сохранить их в порядке файла и просто вывести их, вам не нужна структура данных:

my @items;
while( <DATA> ) {
    chomp;

    if ( /\A(\S+)/ ) {
        print "Fruit: $1\n";
        }
    elsif ( /\A\s+(.+)/ ) {
        print "\tInfo: $1\n";
        }
    }

Если вам нужен немного другой вывод, где каждая строка должна знать фрукт, сохраните это имя в постоянной переменной в цикле while:

my @items;
while( <DATA> ) {
    state $fruit;
    chomp;

    if ( /\A(\S+)/ ) {
        $fruit = $1;
        print "Fruit: $fruit\n";
        }
    elsif ( /\A\s+(.+)/ ) {
        print "\t$fruit: $1\n";
        }
    }

Отличный ответ, я никогда не видел использования @*, не могли бы объяснить, что он делает.

Oliver Gaida 21.02.2023 07:01

->@* — постфиксное разыменование.

brian d foy 21.02.2023 08:35

Другие вопросы по теме