如何在哈希中进行自然排序?

时间:2017-09-05 11:11:34

标签: perl perl-module

use strict;
use warnings;
use 5.010;

my $value;
my $key;

my %hash_keysort = (
  servlet      => 'true',
  servlet_dude => 123,
  hai          => "null",
  array        => 123
);

我希望获得相同的输出。

我尝试使用此程序包Sort::Naturally

即使我使用自然排序,我也无法获得相同的输出。 每次钥匙都在变化。

预期产出:

servlet : true
servlet_dude : 123
hai : null
array : 123

我也尝试了nsort功能。我无法得到钥匙。

我尝试了所有排序类型。我无法解决问题。

我需要每次都以相同的顺序获取密钥。但事情是密钥药水一直在改变。是否有任何逻辑可以获得相同顺序的密钥。 我的目的是每次都需要在不改变魔药的情况下获得钥匙。


更新

#!/usr/bin/perl

use Sort::Naturally;

use strict;
use warnings;

my $value;
my $key;

my %hash_keysort = (
    servlet      => 'true',
    servlet_dude => 123,
    hai          => "null",
    array        => [ 123, "null", "string" ]
);

for my $k ( sort keys %hash_keysort ) {
    printf "%-12s : %s\n", $k, $hash_keysort{$k};
}

实际输出

array        : ARRAY(0x8002afb8)
hai          : null
servlet      : true
servlet_dude : 123

预期

servlet      : true
servlet_dude : 123
hai          : null
array        : 123

更新了一个:     #!的/ usr / bin中/ perl的     用严格;     使用警告;

#binmode STDOUT, ":utf8";
use utf8;
use Data::Dumper;
use JSON;
use Scalar::Util 'reftype';

my $json;
  local $/; #Enable 'slurp' mode
  open my $fh, "<", "my.json";        #opening a file
  $json = <$fh>;
  close $fh;
my $data = decode_json($json);        #decodeing the json data
print "$data\n";
print Dumper($data);                  #prints HASH table
print "\n";

my $key;
my $value;
my $initialtag = '';                      #declaring the intial tag of the 
data
my $hash = {'HASH'=>9998,'ARRAY'=>9987,'SCALAR'=>9996};  # initializing the 
Hash table for opcodes

my $first_key;
my $tag_len;
my $opcode;
my $hex;
my $finalkey_opcode;
my $firstvalue;
my $input;
my $initialtag_2;
my $firstvalue_2;
my $datavalue = check_refernces($data);
if($datavalue){
    $datavalue = check_refernces($datavalue);
}
$datavalue = check_refernces($datavalue);

sub Hash_reference             {                 我的$ input = shift;                 foreach $ key(键%$输入)     {

  $firstvalue = $input->{$key};                 #Acessing the value(Getting 
value from hash)
  print " the value of key $key  $value\n";
  $initialtag = $key;
}
        print "Variable is HASH\n\n";  
        $opcode=$hash->{'HASH'};             #If it is hash Getting opcode 
for object 
        print "the opcode is $opcode\n";

        my $tag_len =  length( $initialtag );          #Finding the length
  print "$tag_len\n";

  my $hex =sprintf('%04X',$tag_len);          #Converting to hexadecimal 
format
  print "$hex\n";
  my $first_key = $hex.$initialtag;           #concatenating the Intail tag 
and hexadecimal value(length of the data)
  print "$first_key\n";

  my $finalkey_opcode=$opcode.$first_key;     #concatenating the opcode and 
data 

  print "$finalkey_opcode\n";
  return $firstvalue;

        }
sub Scalar_reference
{
    print "Variable is SCALAR refernce\n";    # Not a reference
    {
            my $input=shift;
        $opcode=$hash->{'SCALAR'};             #If it is hash Getting opcode 
for object 
        print "the opcode is $opcode\n";
        my $tag_len =  length( $initialtag_2 );          #Finding the length
  print "$tag_len\n";

  my $hex =sprintf('%04X',$tag_len);          #Converting to hexadecimal 
format
  print "$hex\n";
  my $first_key = $hex.$initialtag_2;           #concatenating the Intail 
tag and hexadecimal value(length of the data)
  print "$first_key\n";
    my $finalkey_opcode=$opcode.$first_key;     #concatenating the opcode 
and data 
  print "$finalkey_opcode\n";
  return $firstvalue_2;
}
}
sub Array_refernce
{
    print "Variable is ARRAY\n\n";        # Reference to a ARRAY
}

sub code_refernce
{
    print "Variable is CODE\n\n";         # Reference to a CODE
}


sub check_refernces
{
    my $input = shift;
    my $returnvalue;
    if (ref($input)eq 'SCALAR')
  {
    Scalar_reference();
  }
    elsif (ref($input)eq 'HASH')
    {

        $returnvalue = Hash_reference($input);
         # Reference to a hash
     }
    elsif (ref($input)eq 'ARRAY')
    {
        Array_refernce();
    }
    elsif (ref($value)eq 'CODE')
    {
        code_refernce();
    }

}

数据文件是: “web-app”:{   “小服务程序”:
    {       “servlet-name”:是的,       “servlet-class”:123,       “海”:空,       “阵列”:[123,NULL, “字符串”

    }}

预期产量: servlet:是的 servlet_dude:123 海:空 数组:ARRAY(0x8002afb8)

如何获得相同的输出。

2 个答案:

答案 0 :(得分:6)

Perl哈希的元素按设计随机排列。您无法对哈希做任何事情来设置其内容的顺序。

可以做的是按特定顺序处理或输出哈希的元素。例如

for my $k ( sort keys %hash_keysort ) {
    printf "%-12s : %s\n", $k, $hash_keysort{$k};
}

如果您需要更多帮助,那么您必须改进您的问题。特别是你需要显示你使用过的代码。 &#34;我尝试使用此程序包Sort::Naturally&#34; 没有足够的信息。

如果您希望输出按排序以外的特定顺序排列,那么唯一的方法是单独定义该顺序。

my @keys = qw/ servlet servlet_dude hai array /;

for my $k ( @keys ) {
    my $v = $hash_keysort{$k};
    $v = $v->[0] if ref $v;
    printf "%-12s : %s\n", $k, $v;
}

答案 1 :(得分:0)

从更新开始,它不再是排序问题。您正在寻找的订单不适用于任何类型的例行程序。相反,如果有一组离散键并且您希望按该顺序输出,则可以创建一个用于迭代的数组:

#!/usr/bin/perl
use strict;
use warnings;

my $value;
my $key;
my %hash_keysort = (servlet => 'true',servlet_dude => 123,hai =>"null", array => [123,"null","string"]);

my @wanted = qw(servlet servlet_dude hai array);
for my $k ( @wanted ) {
    printf "%-12s : %s\n", $k, $hash_keysort{$k};
}

这将允许您始终按所需顺序获取输出。