首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Perl :排序后尝试对数组进行排序。

Perl :排序后尝试对数组进行排序。
EN

Stack Overflow用户
提问于 2015-04-25 06:22:13
回答 2查看 103关注 0票数 1

我目前正在编写一个perl脚本,其中我引用了一个引用数组(学生)。将散列引用添加到数组之后。现在,我将引用添加到学生数组中,然后询问用户如何对它们进行排序。这里会让人感到困惑。我不知道如何尊重排序的数组。使用dumper,我可以得到排序数组,但在一个无组织的输出中。如何在排序后对哈希引用数组进行排序?

代码语言:javascript
运行
复制
#!bin/usr/perl
use strict;
use warnings;
use Data::Dumper;
use 5.010;
#reference to a var $r = \$var; Deferencing $$r
#reference to an array $r = \@var ; Deferencing @$r
#referenc to  a hash $r = \%var ; deferencing %$r

my $filename = $ARGV[0];
my $students = [];




open ( INPUT_FILE , '<', "$filename" ) or die "Could not open to read \n ";


sub readLines{
    
    while(my $currentLine = <INPUT_FILE>){
        chomp($currentLine);
        my @myLine = split(/\s+/,$currentLine);
        my %temphash = (
        name => "$myLine[0]",
        age  => "$myLine[1]",
        GPA  => "$myLine[2]",
        MA   => "$myLine[3]"
        );
        pushToStudents(\%temphash);
    }
    
}

sub pushToStudents{
    my $data = shift;
    push $students ,$data;
}

sub printData{
    
    my $COMMAND = shift;
    
    if($COMMAND eq "sort up"){
        my @sortup = sort{ $a->{name} cmp $b->{name} } @$students;
        print Dumper @sortup;
        
    }elsif($COMMAND eq "sort down"){
        my @sortdown = sort{ $b->{name} cmp $a->{name} } @$students;
        print Dumper @sortdown;
        //find a way to deference so to make a more organize user friendly read.
        
    }else{
        print "\n quit";
    }
    
    
}

readLines();
#Output in random, the ordering of each users data is random
printf"please choose display order : ";
my $response = <STDIN>;
chomp $response;
printData($response);
EN

Stack Overflow用户

回答已采纳

发布于 2015-04-25 10:27:27

这里的问题是,您需要Dumper提供一个有组织的输出。它没有。它转储数据结构以使调试更容易。关键问题是散列是显式无序的数据结构--它们是键值映射,不会产生任何输出顺序。

参考perldata

请注意,仅仅因为哈希是按该顺序初始化的,并不意味着它是按该顺序出现的。

特别是keys函数:

散列项以明显的随机顺序返回。实际的随机顺序特定于给定的哈希;对两个散列的相同操作可能导致每个散列的顺序不同。

perlsec中有一个完整的部分详细地解释了这一点,但只需说明-散列是随机顺序,这意味着当您按名称对学生排序时,没有对每个学生的键值对进行排序。

我建议不要:

代码语言:javascript
运行
复制
my @sortdown = sort{ $b->{name} cmp $a->{name} } @$students;
print Dumper @sortdown;

你最好用一个slice

代码语言:javascript
运行
复制
my @field_order = qw ( name age GPA MA );

foreach my $student ( sort { $b -> {name} cmp $a -> {name} } @$students ) {
   print @{$student}{@field_order}, "\n";
}

数组(@field_order)是显式排序的,因此您将始终以相同的顺序打印您的学生字段。(恐怕您的示例还没有完全测试,因为我没有您的源数据,但是这种方法适用于示例数据片段)。

如果您也需要打印这些键,那么您可能需要一个foreach循环:

代码语言:javascript
运行
复制
foreach my $field ( @field_order ) {
    print "$field => ", $student->{$field},"\n";
}

或者更简洁:

代码语言:javascript
运行
复制
print "$_ => ", $student -> {$_},"\n" for @field_order;

虽然我不太喜欢,但这可能是口味的问题。

票数 2
EN
查看全部 2 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/29861771

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档