【问题标题】:Sort Hash Key and Value simultaneously Perl同时对哈希键和值进行排序 Perl
【发布时间】:2019-03-17 05:49:06
【问题描述】:

我有一个哈希值,我想按数字升序对键进行排序,并且 它的值按字母升序排列。

#!/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";
}   

想要的输入是这样的,我想打印出排序后的键和值。

%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', ],
);

附加问题,如何打印第一个不同值的key和标量值

想要的输出:

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

【问题讨论】:

  • 请一次一个问题。
  • @Schwern,好的。感谢您的积极评价!

标签: perl sorting hash


【解决方案1】:

哈希键没有定义的顺序。通常,您在遍历哈希时对键进行排序。

可以在遍历哈希时对值进行排序。

# 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";
}

请注意,默认情况下sort 按 ASCII 顺序排序为字符串。这意味着sort keys %KEY_VALUE 不是按数字排序,而是按字符串排序。 sort(2,3,10)(10,2,3)"10" 小于 "2" 就像 "ah" 小于 "b"。请务必使用sort { $a &lt;=&gt; $b } 进行数字排序,使用sort { $a cmp $b } 进行字符串排序。

您可以使用不同的数据结构,例如Tie::Ixhash,尽管绑定会显着降低性能。通常,除非您的哈希变得非常大,否则最好就地排序。

【讨论】:

  • 感谢您提供这些知识!顺便说一句,对于我的其他问题/问题,使用哈希是否可行?
  • @DanialHaris 重要的是要意识到该部分与哈希无关。这是你想要对数组做的事情。它们恰好是散列中的值。考虑如何将数组['A','A','B','C','D'] 转换为0, 2, 3, 4。把它编码。然后将该代码放入循环中以处理散列的每个值。或者更好的是,将该代码放入一个函数中,并对循环中的每个值使用该函数。
【解决方案2】:

您无法对哈希进行排序,您最多可以将其打印排序(或将排序后的键保存在另一个数组中)。找到第一个值的位置可以用first_index;我们使用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";
}

【讨论】:

  • 我明白了,这就是为什么哈希的值即使我已经排序也无法更新。感谢您提供这些知识。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-06-02
  • 2015-03-12
  • 1970-01-01
  • 1970-01-01
  • 2011-10-30
  • 2018-05-10
  • 1970-01-01
相关资源
最近更新 更多