读取文本文件并在perl中写入二维数组?

时间:2017-12-29 10:21:12

标签: perl multidimensional-array hash

#!/usr/bin/perl

use strict;
use warnings;
use utf8;
use open ':encoding(UTF-8)', ':std';
use List::Util qw( sum );

my $filename =  'data1.txt';

open(my $fh, '<:encoding(UTF-8)', $filename)
    or die "Could not open file '$filename' $!";

while (my $row = <$fh>) {
    chomp $row;
    print "$row\n";
}

my $filename2 = 'data2.txt';

open(my $fh2, '<:encoding(UTF-8)', $filename2)
    or die "Could not open file '$filename2' $!";

while (my $row = <$fh2>) {
    chomp $row;
    print "$row\n";
}

my @last = ();

my %grades = (
    Ahmet => {
        quiz1 => 97,
        quiz2 => 67,
        quiz3 => 93,
    },
    Su => {
        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){
    push @last, "$name: $sum{$name}\n";
}

my %grades2 = (
    Bugra => {
        quiz1 => 33,
        quiz2 => 41,
        quiz3 => 59,
    },
    Lale => {
        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){
    push @last, "$name: $sum2{$name}\n";
}

my @last1 = sort { lc($a) cmp lc($b) } @last;

print @last1;

这是我的代码。我想从文本文件中获取值(结婚10 65 23)并写入二维数组。我管理数组分别读取文本文件的结尾,例如grade1grade2 data1.txtdata2.txt。我可以提取值,但我无法写入二维数组。结果也是正确的。

2 个答案:

答案 0 :(得分:0)

我将您的问题视为 如何从文件%grade1%grade2填充哈希data1.txtdata2.txt

我还假设您的文件data1.txtdata2.txt具有以下结构(以空格分隔):

marry 10 65 23
john 20 30 40

我建议编写一个函数,将文件名作为参数,并返回对填充哈希的引用:

sub read_grades_from_file
{
    my $filename = shift;
    my $result   = {};

    open( my $fh, '<:encoding(UTF-8)', $filename )
      or die "Could not open file '$filename' $!\n";
    while ( my $row = <$fh> ) {
        next unless $row =~ /\S/;    # skip empty lines
        my ( $name, $quiz1, $quiz2, $quiz3 ) = split( ' ', $row );
        $result->{$name} = {
            quiz1 => $quiz1,
            quiz2 => $quiz2,
            quiz3 => $quiz3,
        };
    }
    close($fh);
    return $result;
}

该功能使用如下:

my $result = read_grades_from_file('data1.txt');    # returns hashref
my %grade1 = %{$result};                            # dereference $result to make it a hash

$result = read_grades_from_file('data2.txt');
my %grade2 = %{$result};

read_grades_from_file的结果是哈希的引用,因此必须取消引用,然后将其分配给%grade。因此这两个步骤。

答案 1 :(得分:0)

您使用的数据结构可能过于复杂。例如,您可能只需要一个%grades哈希值。

以下内容将从两个输入文件中的空格或制表符分隔记录中获取数据 - 忽略注释或空行。

my %grades;
while (1) {
  my $row1 = <$data1>;
  my $row2 = <$data2>;
  last unless (defined $row1 or defined $row2);
  chomp ($row1, $row2);
  if (defined $row1 and $row1 !~ /(^#|^$)/) {
    my ($name, @quizzes) = split /[ \t]/, $row1, 4;
    $grades{$name}{'grades1'} = sum(@quizzes);
  }
  if (defined $row2 and $row1 !~ /(^#|^$)/) {
    my ($name, @quizzes) = split /[ \t]/, $row2, 4;
    $grades{$name}{'grades2'} = sum(@quizzes);
  }
}

要打印到STDOUT,您可以尝试以下操作。

print "Name\tMarks 1\tMarks 2", $/;

for (keys %grades) {
  my $name = $grades{$_};
  print $_, "\t", $name->{grades1} || '?', "\t", $name->{grades2} || '?', "\t", $/;
}

将data1.txt作为

# Grades
Bugra 33 41 59
Mary 10 65 23
Lale 79 31 62

和data2.txt为

# Grades 2
Bugra 49 32 57
Lale 79 31 62
Peter 21 34 42

输出如下所示。

Name    Marks 1 Marks 2
Peter   ?       97
Lale    172     172
Bugra   133     138
Mary    98      ?

(A'?'表示两个输入文件之一中没有指定学生的记录。)