Как распечатать сложный хеш без повторения клавиш второго уровня? - PullRequest
2 голосов
/ 12 июля 2011

Привет! У меня есть хэш, содержащий имя класса, количество учащихся и имена учащихся.
Как распечатать этот хэш, не повторяя ключей второго уровня.
Пример: мои данные, которые яЗаполните мой хэш - Наука, 3 ученика, а именно Джордж, Лиза, Матиас и математик, 4 ученика: Питер, Джордж, Анна, Мартин.

my %register=();

$register{$className}->{$count_students}=$student_name; # Fill the hash.

  foreach my $key ( keys %register ){      

   print "$key: ";

   foreach my $class ( keys %{ $register{$key} } ){

       print "$class=$register{$key}->{$class}\n";

   }  
}

Я получаю результат как:

Наука_класса: 2 = Лиза
1 = Джордж
3 = Матиас
Математический_класс: 2 = Анна
1 =Мартин
3 = Петр
4 = Джордж

Но я хочу, чтобы мой результат был:

Science_class: 3 -> Лиза, Джордж, Матиас
Math_class: 4 ->Анна, Мартин, Питер, Джордж

Как мне исправить мой сценарий?Помоги мне.

Ответы [ 3 ]

5 голосов
/ 12 июля 2011

Вы можете получить количество записей на втором уровне с помощью функции keys в скалярном контексте, и вы можете получить только значения на втором уровне с помощью values функция.

#!/usr/bin/perl

use strict;
use warnings;

my %register = (
    Science_class => {
        1 => "George",
        2 => "Lisa",
        3 => "Mathias",
    },
    Math_class => {
        1 => "Martin",
        2 => "Anna",
        3 => "Peter",
        4 => "George",
    }
);

for my $class (keys %register) {
    print "$class: ", scalar keys %{$register{$class}},
        " ", join(", ", values %{$register{$class}}), "\n";
}

Однако, учитывая структуру ваших данных, хэш arrayrefs имеет больше смысла:

#!/usr/bin/perl

use strict;
use warnings;

my %register = (
    Science_class => [
        "George",
        "Lisa",
        "Mathias",
    ],
    Math_class => [
        "Martin",
        "Anna",
        "Peter",
        "George",
    ]
);

for my $class (keys %register) {
    print "$class: ", scalar @{$register{$class}},
        " ", join(", ", @{$register{$class}}), "\n";
}

Вы можете найти чтение perldoc perldsc полезно для понимания того, как создавать и манипулировать структурами данных в Perl 5.

2 голосов
/ 12 июля 2011

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

$numkeys = keys $register{$key};
print "$key: $numkeys ->";

Далее следуют имена в этом массиве. Нет необходимости иметь внутренний цикл для отображения имен, просто используйте ключи:

print join(", ", keys $register{$key});
1 голос
/ 12 июля 2011

Нет необходимости хранить количество учеников в каждом классе, так как вы можете просто посчитать количество учеников в вашей структуре.(И поэтому ваши показатели не будут синхронизированы, когда ваша структура изменится.) Я бы порекомендовал использовать хэш массивов, например:

use strict;
use warnings;

my %register;

# populate the hash, e.g.:
my $classname = 'science_class';
push @{ $register{$classname} }, 'Lisa';
push @{ $register{$classname} }, 'George';
push @{ $register{$classname} }, 'Mathias';

# print the results:

foreach my $class( sort keys %register ) { 
    print $class, ' : ';
    my @students = @{ $register{$class};
    print scalar( @students ), ' = ';   # number of elements in the array
    print join ', ', @students;
    print "\n";
}
...