perl - 使用perl进行哈希键排序?

标签 perl sorting hash

我需要使用 perl 对哈希键进行排序,我还需要允许键中重复。因此,我计划检查 perl
中的 exists 方法是否存在,然后我增加最后一个数字,然后将其存储到哈希中。 我尝试了以下代码:

use strict;
use warnings;
use iPerl::Basic qw(_save_file _open_file);
my $xml = $ARGV[0];
my ($xmlcnt,$backcnt,$refcnt,$name,$year) = "";
my %sort = ();
if(($#ARGV != 0) or(not -f "$xml") or($xml!~ m{\.xml$}i)){ 
    print_exit("\t\tSYSTAX ERROR: <EXE> <xml File>\n\n")
};
$xmlcnt=_open_file($xml);
$xmlcnt =~ s{<back(?: [^>]+)?>(?:(?!</?back[ >]).)*</back>}{
    $backcnt = $&;

    while($backcnt =~ m{<ref(?: [^>]+)?>(?:(?!<ref[ >]).)*</ref>}igs){
        $refcnt = $&;
        $name = $1 if($refcnt =~ m{<person-group(?: [^>]+)?>((?:(?!</?person-group[ >]).)*)</person-group>}is);
        $year = $1 if($refcnt =~ m{<year>((?:(?!</?year[ >]).)*)</year>}is);
        $name =~ s{</?(?:string-name|surname|given-names)>}{}ig;
        my $count = 1;
        my $keys="$name $year\E$count";

        if(exists ($sort{$keys})){

            $keys =~ s{(\d)$}{my $icr=$1;$icr++;qq($icr)}e;

            #print"$keys\n";
            $sort{$keys}="$refcnt";

        }
        else
        {
            $sort{$keys}="$refcnt";
        }


print join("\n",keys %sort);
    }
qq($backcnt)
}igse;

    my @keys = sort {
 $sort{$a} <=>  $sort{$b}
# or
# "\L$a" cmp "\L$b"
} keys %sort;
# print join("\n",@keys);
sub print_exit {
    my $msg = shift;
    #print "\n$msg";
    exit;
}

请问谁能告诉我这里出了什么问题吗?
输入:

thieooieroh
apple
apple
highefhfe
bufghifeh

输出:

 apple
 apple
 bufghifeh
 highefhfe
 thieooieroh

提前致谢。

最佳答案

从非常简单地查看您的代码来看,您似乎希望将引用计数存储为散列中的值,并且能够对单个键进行多个计数。通过使用数组哈希(通常缩写为 HoA)可以轻松实现这一点。根据定义,每个键必须是唯一的,但关联的值可以是引用,允许您在该键下存储多个项目,或者构建更复杂的数据结构。

#!/usr/bin/env perl    

use strict;
use warnings;
use 5.010;

my %hash;

while (my $line = <DATA>) {
  chomp $line;
  my ($key, $count) = split ',', $line;
  push @{$hash{$key}}, $count;
}

for my $key (sort keys %hash) {
  my $values = $hash{$key};
  for (@$values) {
    say "$key ($_)";
  }
} 

__DATA__
thieooieroh,1
apple,2
apple,3
highefhfe,4
bufghifeh,5

输出:

apple (2)
apple (3)
bufghifeh (5)
highefhfe (4)
thieooieroh (1)

如果您实际上并不关心每个键存储多个数据项,而只关心每个键出现的次数,那就更简单了。将上面代码中的两个循环改为:

while (my $line = <DATA>) {
  chomp $line;
  $hash{$line}++;
}

for my $key (sort keys %hash) {
  say $key for 1 .. $hash{$key};
}

然后你就得到了输出

apple
apple
bufghifeh
highefhfe
thieooieroh

至于您发布的其余代码,请不要尝试使用正则表达式解析 XML。任意 XML无法通过正则表达式进行非常粗略的第一近似解析,因为 XML 在结构上不是“正则”。 CPAN 上有许多优秀的 XML 解析模块,它们可以为您正确解析 XML,同时比尝试编写自己的解析器所需的工作量要少得多。使用其中之一。不是正则表达式。

关于perl - 使用perl进行哈希键排序?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27935868/

相关文章:

mysql - sql查询年/月排序

python - 向 "is hashable"询问 Python 值

linux - 自动重新创建许多不同的链接到重命名的目录或文件

perl - 无法使用 mojolicious 以 xml 形式发送 HTTP 响应

python - 按值将 Python 3 字典排序回字典而不是元组列表

php - 在 PHP 中向排序数组中插入元素有哪些更好的方法

ruby - "exception class/object expected"ruby​​ 无法挽救哈希对象

c - 与传统的分段哈希相比,使用上下文触发分段哈希有什么好处?

Perl CGI 可靠地读取 url_param 和 param

perl - 如何在 Perl 中保留散列的顺序?