简体   繁体   English

同时对哈希键和值进行排序Perl

[英]Sort Hash Key and Value simultaneously Perl

I have a hash that I want to sort the keys numerically in ascending order and its values in ascending alphabetically manner. 我有一个哈希,我想按升序对键进行数字排序,并按字母升序对键的值进行排序。

#!/usr/bin/perl
use warnings;
use strict;
use List::MoreUtils;
use Tie::IxHash;    

my %KEY_VALUE;
#tie %KEY_VALUE,'Tie::IxHash';


my %KEY_VALUE= (
    0 => [ 'A', 'C', 'B', 'A' ,'D'],
    5 => [ 'D', 'F', 'E', ],
    2 => [ 'Z', 'X', 'Y' ],
    4 => [ 'E', 'R', 'M' ],
    3 => [ 'A', 'B', 'B', 'A' ],
    1 => [ 'C', 'C', 'F', 'E' ],
    );

#while (my ($k, $av) = each %KEY_VALUE) 
#{
#  print "$k @$av\n ";
#}

#Sort the key numerically   
foreach my $key (sort keys %KEY_VALUE)
{
 print "$key\n";
}

#To sort the value alphabetically
foreach my $key (sort {$KEY_VALUE{$a} cmp $KEY_VALUE{$b}} keys %KEY_VALUE){
       print "$key: $KEY_VALUE{$key}\n";
}   

The wanted input is like this, and I want to print out the sorted keys and values. 所需的输入是这样的,我想打印出排序的键和值。

%KEY_VALUE= (
    0 => [ 'A','A','B','C','D'],
    1 => [ 'C','C','E','F' ],
    2 => [ 'X','Y','Z' ],
    3 => [ 'A', 'A', 'B', 'B' ],
    4 => [ 'E','M','R' ],
    5 => [ 'D','E','F', ],
);

Additional problem, how to print the key and the scalar value of the first different value 附加问题,如何打印键和第一个不同值的标量值

Wanted Output: 想要的输出:

KEY= 0  VALUE:0 2 3 4   #The scalar value of first A B C D, start with 0
KEY= 1  VALUE:0 2 3     #The scalar value of first C E F
KEY= 2  VALUE:0 1 2     #The scalar value of first X Y Z
KEY= 3  VALUE:0 2       #The scalar value of first A B
KEY= 4  VALUE:0 1 2     #The scalar value of first E M R
KEY= 5  VALUE:0 1 2     #The scalar value of first D E F

Hash keys have no defined order. 哈希键没有定义的顺序。 Generally you sort the keys as you're iterating through the hash. 通常,您在遍历哈希时对键进行排序。

The values can be sorted as you iterate through the hash. 这些值可以在您遍历哈希时进行排序。

# Iterate through the keys in numeric order.
for my $key (sort {$a <=> $b } keys %hash) {
    # Get the value
    my $val = $hash{$key};

    # Sort it in place
    @$val = sort { $a cmp $b } @$val;

    # Display it
    say "$key -> @$val";
}

Note that by default sort sorts in ASCII order as strings. 请注意,默认情况下, sort按ASCII顺序以字符串sort That means sort keys %KEY_VALUE is not sorting as numbers but as strings. 这意味着sort keys %KEY_VALUE不是按数字而是按字符串排序。 sort(2,3,10) is (10,2,3) . sort(2,3,10)(10,2,3) "10" is less than "2" like "ah" is less than "b" . "10"小于"2"例如"ah"小于"b" Be sure to use sort { $a <=> $b } for numeric sorting and sort { $a cmp $b } for strings. 确保对数字排序使用sort { $a <=> $b } ,对字符串使用sort { $a cmp $b }

You could use a different data structure such as Tie::Ixhash though tying has a significant performance penalty. 您可以使用其他数据结构,例如Tie :: Ixhash,尽管绑定会严重影响性能。 Generally it's better to sort in place unless your hash gets very large. 通常,除非哈希值非常大,否则最好将其排序。

You can't sort a hash, you can at best print it sorted (or keep the sorted keys in another array). 您无法对哈希进行排序,最多只能将其打印为已排序(或将已排序的键保留在另一个数组中)。 Finding the position of the first value can be done with first_index ; 可以使用first_index来找到第一个值的位置; we remove duplicates with uniq . 我们使用uniq删除重复项。

foreach my $key (sort keys %KEY_VALUE) {
  my @value = @{$KEY_VALUE{$key}};
  my @indices = map { my $e = $_; first_index { $_ eq $e } @value } (uniq (sort @value));
  print "$key: " . (join ', ', @indices) . "\n";
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM