二维哈希数据输出?

时间:2017-12-26 20:45:44

标签: perl sorting join hash printing

这是我的代码。在这个过程结束时,我想按升序收集名称和总和结果并想要打印。我试图把@ sum1和@ sum2作为但是它不能知道@sum我怎么能这样做,或者任何想法都是非常有价值的。

#!/usr/bin/perl

use strict;
use warnings;
use List::Util qw( sum );
use Data::Dumper qw(Dumper);

my %grades;
$grades{"Ahmet"}{quiz1}  = 97;
$grades{"Ahmet"}{quiz2}  = 67;
$grades{"Ahmet"}{quiz3}  = 93;
$grades{"Mehmet"}{quiz1} = 88;
$grades{"Mehmet"}{quiz2} = 82;
$grades{"Mehmet"}{quiz3} = 99;

print Dumper \%grades;
print "----------------\n";

foreach my $name ( sort keys %grades ) {
    my %hash1 = (
        'Ahmet'  => [ 97, 67, 93 ],
        'Mehmet' => [ 88, 82, 99 ],
    );

    my @sums;
    for my $key ( keys %hash1 ) {
        my $sum = sum @{ $hash1{$key} };
        push @sums, "$key: $sum\n";
    }

    foreach my $sum ( keys %{ $grades{$name} } ) {
        print "$name : $grades{$name}{$sum}\n";
    }

    print @sums;
}

foreach my $name ( sort keys %grades ) {
    print "$grades{$name}\n";
}

my %grades2;
$grades2{"Merve"}{quiz1} = 33;
$grades2{"Merve"}{quiz2} = 41;
$grades2{"Merve"}{quiz3} = 59;
$grades2{"Aslı"}{quiz1} = 79;
$grades2{"Aslı"}{quiz2} = 31;
$grades2{"Aslı"}{quiz3} = 62;

print Dumper \%grades2;
print "----------------\n";

foreach my $name2 ( sort keys %grades2 ) {
    my %hash = (
        'Merve' => [ 33, 41, 59 ],
        'Aslı' => [ 79, 31, 62 ],
    );

    my @sums2;
    for my $key ( keys %hash ) {
        my $sum = sum @{ $hash{$key} };
        push @sums2, "$key: $sum\n";
    }

    foreach my $sum ( keys %{ $grades2{$name2} } ) {
        print "$name2 : $grades2{$name2}{$sum}\n";
    }

    print @sums2;

}

foreach my $name2 ( sort keys %grades2 ) {
    print "$grades2{$name2}\n";
}

my %info;

$info{$_} .= "A" for keys %grades;
$info{$_} .= "B" for keys %grades2;

for ( sort keys %info ) {
    print "$_ : $info{$_}\n";
}

2 个答案:

答案 0 :(得分:1)

您似乎在代码中复制了一些信息。填充%成绩后,无需创建%哈希 - 它可以直接从%成绩中提取。

要填充哈希值,您不必一直重复键,描述子结构如下所示。

此外,您的代码包含“ı”,它不是ASCII字符。告诉Perl通过使用utf8并声明输出的编码会更好。

要按总和对输出进行排序,请使用sort函数和一个比较哈希元素的自定义块:

#!/usr/bin/perl
use strict;
use warnings;
use utf8;
use open ':encoding(UTF-8)', ':std';

use List::Util qw( sum );

my %grades = (
    Ahmet => {
        quiz1 => 97,
        quiz2 => 67,
        quiz3 => 93,
    },
    Mehmet => {
        quiz1  => 88,
        quiz2  => 82,
        quiz3  => 99,
    }
);

my %sum;
for my $name (keys %grades)
  {
    $sum{$name} = sum(values %{ $grades{$name} });
}
for my $name (sort { $sum{$a} <=> $sum{$b} } keys %sum)
  {
    print $name, ' ', $sum{$name}, "\n";
  }

my %grades2 = (
    Merve => {
        quiz1 => 33,
        quiz2 => 41,
        quiz3 => 59,
    },
    Aslı => {
        quiz1 => 79,
        quiz2 => 31,
        quiz3 => 62,
    },
);

my %sum2;
for my $name (keys %grades2)
  {
    $sum2{$name} = sum(values %{ $grades2{$name} });
  }
for my $name (sort { $sum2{$a} <=> $sum2{$b} } keys %sum2)
  {
    print $name, ' ', $sum2{$name}, "\n";
  }

答案 1 :(得分:1)

这是一种方法。你正在创建一个散列引用的散列,这是明确地这样做的(我已经添加了一个学生来使这个例子更有趣):

my %grades = (
  'Ahmet' => {
    quiz1 => 97,
    quiz2 => 67,
    quiz3 => 93,
  },
  'Mehmet' => {
    quiz1 => 88,
    quiz2 => 82,
    quiz3 => 99,
  },
  'Abdul' => {
    quiz1 => 99,
    quiz2 => 89,
    quiz3 => 99,
  },
);

要打印学生及其成绩,您可以使用:

# Printing the students and grades
foreach my $student ( keys %grades ) {
  print $student, ":\n";
  foreach my $test ( keys %{$grades{$student}} ) {
    print " - ", $test, "\t", $grades{$student}{$test}, "\n";
  }
}

为每个学生生成总和:

# Generating a sum for each student
my %sums;
foreach my $student ( keys %grades ) {
  $sums{$student} = sum0 map { $grades{$student}{$_} } keys %{$grades{$student}};
}

我使用sum0,当给出的列表为空时,它将返回0而不是undef。您应该在开头使用use List::Util qw( sum0 );

然后按升序打印生成的总和:

# Printing the sum
foreach my $student ( sort { $sums{$a} <=> $sums{$b} } keys %sums ) {
  print $student, ":\t", $sums{$student}, "\n";
}

对于相反的顺序,您可以使用sort { $sums{$b} <=> $sums{$a} } keys %sums。对于其余代码,您也可以这样做......

学生的输出:

Ahmet:
 - quiz1        97
 - quiz3        93
 - quiz2        67
Mehmet:
 - quiz2        82
 - quiz3        99
 - quiz1        88
Abdul:
 - quiz2        89
 - quiz3        99
 - quiz1        99

然后是成绩总和:

Ahmet:  257
Mehmet: 269
Abdul:  287