2010-08-20 8 views
8

Perl: 如何使用JSON :: PP对一个复杂结构进行排序?perl:如何对“根”键属性以外的东西对JSON结构进行排序

从JSON文件:

正如 JSON :: PP范围排序例程运行,给定的子程序 名和特殊变量$ A,$ B 将开始“JSON :: PP ::”。

这里是我的尝试,似乎不工作

open my $fh, ">", $file or warn " exportAsJSON: can't open file: '$file': $!"; 
print $fh $coder->sort_by(sub {$_->{column_def}->{$JSON::PP::a} cmp $_->{column_def}->{$JSON::PP::b} })->encode(\%json); 
close $fh; 

我想通过键进行排序,然后在下面的“COLUMN_DEF”的属性键COLUMN_DEF属性,即 密度,depth_in_m,mag_sus :

{ 
    "column_def": 
     { 
      "depth_in_m": 
       { 
        "names":"depth_in_m", 
        "pos":"0" 
       }, 
      "mag_sus": 
       { 
        "names": 
         { 
          "A_ALIAS":"Mag-Sus.", 
          "A_DESC":"magnetic susceptibility in SI", 
          "ATTRIBUTE":"MAG_SUS" 
         }, 
        "pos":"2" 
       }, 
      "density": 
       { 
        "names": 
         { 
          "A_ALIAS":"Density", 
          "A_DESC":"density in gm\/cc", 
          "ATTRIBUTE":"DENSITY" 
         }, 
        "pos":"1" 
       } 
     }, 
    "data": 
     { 
      "depth_in_m":"14.635", 
      "mag_sus":"n.a.", 
      "density":"n.a." 
     } 
} 
+3

我很想知道为什么你要排序的东西,将解析为散列 - 这没有固有的顺序。 – 2010-08-20 15:01:56

+1

@熊会吃掉你:事实上,内存中的表示没有固有的顺序。我想将排序后的散列结构保存到一个文件(或临时文件)中,进行差异化和目视检查(以及之后的更复杂的事情)。 – knb 2010-08-23 10:02:03

回答

14

我不能肯定我明白你怎么想的JSON输出进行排序 - 除了通过哈希键排序。如果这就是你想要的,只要通过canonical方法一个真实的论点。

use strict; 
use warnings; 

use JSON::PP; 

# A simple hash-of-hashes for exploration. 
my $h = { 
    Z => { c => 1, d => 2 }, 
    A => { a => 3, r => 4 }, 
    B => { c => 5, x => 6 }, 
    S => { q => 7, d => 8 }, 
}; 

my $js = JSON::PP->new; 
$js->canonical(1); 

my $output = $js->encode($h); 
print $output; 

如果你使用的sort_by方法,它没有任何意义的sort块中使用$_:那会是什么表现?从文档中不清楚sort_by代码将会收到什么样的论据。使用Data::Dumper这样的:

use Data::Dumper qw(Dumper); 

my $sorter = sub { 
    # See what's going on. 
    print "$JSON::PP::a cmp $JSON::PP::b\n"; 
    print Dumper(\@_, $_); 
    <STDIN>; 

    # Sort hash keys alphabetically. 
    $JSON::PP::a cmp $JSON::PP::b; 
}; 

my $output = $js->sort_by($sorter)->encode($h); 

可以推断sort_by是这样的:(1)它接收两个参数,JSON::PP对象和哈希REF目前正在与合作;和(2)$JSON::PP::a$JSON::PP::b变量保存被比较的散列键。 但是请注意这个哈希引用指的是JSON输出,因为它是从叶节点向上构建的。它不涉及您的原始数据结构。这似乎使编写比较器的任务变得有点棘手。祝你好运。

my $sorter = sub { 
    my ($json_pp_object, $hash_ref) = @_; 

    # Write your own comparator here. 
}; 

my $output = $js->sort_by($sorter)->encode($h); 
+0

意向排序: 首先按哈希键字母顺序排列, 按字母顺序排列依次排列第一个哈希引用子键。 或者,(第二个)用“pos”的值(在弄清楚嵌套结构上的排序是如何工作的)的数值。 – knb 2010-08-23 10:38:20

+0

个人记事:这是一个类似的问题:http://stackoverflow.com/questions/4041762/iterating-over-a-javascript-object-in-sort-order-based-on-particular-key-value-of – knb 2010-11-08 15:57:24

+1

在写你自己的分拣机时请注意。看起来$ JSON :: PP :: VERSION ='2.27200'不会将JSON :: PP对象作为第一个参数。对于最后一个例子,版本> = 2.27200的分拣机需要使用我的$ hashref = shift; – heymatthew 2012-04-01 05:14:21

相关问题