按字母数字排序对散列键进行排序 [英] Sorting hash keys by Alphanumeric sort

查看:139
本文介绍了按字母数字排序对散列键进行排序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我刚刚阅读在Perl中对字母数字哈希键进行排序? 。但是我从Perl开始,并且我不太清楚它。



所以我有一个像这样的散列:

 %hash =(
chr1=> 1,
chr2=> 3,
chr19 => 14,
chr22=> 1,
X=> 2,

我试图获得这样的输出:

  chr1 
chr2
chr19
chr22

但是我获得这样的输出:

  chr1 
chr19
chr2
chr22

我编写了这段代码,但它创建了上面的错误输出:

  foreach my $ chr(sort {$ a cmp $ b} keys(%hash)){
my $ total = $ hash {$ chr};
my $ differentpercent =($ differenthash {$ chr} / $ total)* 100;
my $ round =(int($ differentpercent * 1000))/ 1000;
print$ chr\t $ hash {$ chr} \ t $ differenthash {$ chr} \t $ round \\\
;

$ / code $ / pre
$ b $ p



  chr1 342421 7449 2.175 
chr10 227648 5327 2.34
chr11 220415 4468 2.027
chr12 213263 4578 2.146
chr13 172379 3518 2.04
chr14 143534 2883 2.008
chr15 126441 2588 2.046
chr16 138239 3596 2.601
chr17 122137 3232 2.646
chr18 130275 3252 2.496
chr19 99876 2836 2.839
chr2 366815 8123 2.214

如何解决这个问题?

解决方案

更新 <@ c $ c> Sort :: Naturally 模块的缺点请注意@ Miller的评论。



你所要求的是一种相对复杂的排序方式,它将每个字符串拆分为字母和数字字段,然后按照字母和数字对字母进行排序。



模块 Sort :: Naturally 会按照你的要求做,或者你可以写一些类似这个。您似乎忽略了 X 键,所以我使用与个案无关的排序将它排序到最后。

 使用strict; 
使用警告;

my%hash = map {$ _ => 1} qw(
chr22 chr20 chr19 chr13 chr21 chr16 chr12 chr10 chr18
chr17 chrY chr5 chr5 chr8 chr8 chr4 chr6 chr3 chr6 $

my @sorted_keys = sort {
my @aa = $ a =〜/ ^([A-Za-z] +)(\ d *)/;
my @bb = $ b =〜/ ^([A-Za-z] +)(\ d *)/;
lc $ aa [0] cmp lc $ bb [0]或$ aa [1]< => $ BB [1];
}键%hash;

为@sorted_keys打印$ _\\\
;

输出

  chr1 
chr2
chr3
chr4
chr5
chr6
chr7
chr8
chr9
chr10
chr11
chr12
chr13
chr14
chr15
chr16
chr17
chr18
chr19
chr20
chr21
chr22
chrM
chrX
chrY

使用 Sort :: Naturally 模块(您可能需要安装它),您可以改写它。

 严格使用; 
使用警告;

使用Sort :: Naturally;

my%hash = map {$ _ => 1} qw(
chr22 chr20 chr19 chr13 chr21 chr16 chr12 chr10 chr18
chr17 chrY chr5 chr5 chr8 chr8 chr4 chr6 chr3 chr6 $

my @sorted_keys = nsort keys%hash;

为@sorted_keys打印$ _\\\
;

输出与上述相同。


I have just read the post Sorting alphanumeric hash keys in Perl?. But I am starting with Perl, and I don't understand it very clearly.

So I have a hash like this one:

  %hash = (
        "chr1" => 1,
        "chr2" => 3,
        "chr19" => 14,
        "chr22" => 1,
        "X" => 2,
    )

I'm trying to obtain output like this:

chr1
chr2
chr19
chr22

But I'm obtaining output like this:

chr1
chr19
chr2
chr22

I have written this code, but it is creating the above wrong output:

foreach my $chr (sort {$a cmp $b} keys(%hash)) {
    my $total= $hash{$chr};
    my $differentpercent= ($differenthash{$chr} / $total)*100;
    my $round=(int($differentpercent*1000))/1000;
    print "$chr\t$hash{$chr}\t$differenthash{$chr}\t$round\n";
}

It prints:

chr1    342421    7449    2.175
chr10    227648    5327    2.34
chr11    220415    4468    2.027
chr12    213263    4578    2.146
chr13    172379    3518    2.04
chr14    143534    2883    2.008
chr15    126441    2588    2.046
chr16    138239    3596    2.601
chr17    122137    3232    2.646
chr18    130275    3252    2.496
chr19    99876    2836    2.839
chr2    366815    8123    2.214

How can I fix this?

解决方案

Update Note @Miller's comment below on some shortcomings of the Sort::Naturally module.

What you are asking for is a relatively complicated sort that splits each string into alphabetical and numeric fields, and then sorts the letters lexically and the numbers by value.

The module Sort::Naturally will do what you ask, or you can write something like this. You appear to have ignored the X key, so I have sorted it to the end using a case-independent sort.

use strict;
use warnings;

my %hash = map { $_ => 1 } qw(
    chr22  chr20  chr19  chr13  chr21  chr16  chr12  chr10  chr18
    chr17  chrY   chr5   chrX   chr8   chr14  chr6   chr3   chr9
    chr1   chrM   chr11  chr2   chr7   chr4   chr15
);

my @sorted_keys = sort {
    my @aa = $a =~ /^([A-Za-z]+)(\d*)/;
    my @bb = $b =~ /^([A-Za-z]+)(\d*)/;
    lc $aa[0] cmp lc $bb[0] or $aa[1] <=> $bb[1];
} keys %hash;

print "$_\n" for @sorted_keys;

output

chr1
chr2
chr3
chr4
chr5
chr6
chr7
chr8
chr9
chr10
chr11
chr12
chr13
chr14
chr15
chr16
chr17
chr18
chr19
chr20
chr21
chr22
chrM
chrX
chrY

Using the Sort::Naturally module (you will probably have to install it) you could write this instead.

use strict;
use warnings;

use Sort::Naturally;

my %hash = map { $_ => 1 } qw(
    chr22  chr20  chr19  chr13  chr21  chr16  chr12  chr10  chr18
    chr17  chrY   chr5   chrX   chr8   chr14  chr6   chr3   chr9
    chr1   chrM   chr11  chr2   chr7   chr4   chr15
);

my @sorted_keys = nsort keys %hash;

print "$_\n" for @sorted_keys;

The output is identical to the above.

这篇关于按字母数字排序对散列键进行排序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆