Schwartzian Transform(施瓦茨变换) 是perl中一种高效的排序算法 ,详见http://en.wikipedia.org/wiki/Schwartzian_transform
在平时工作中,会有非常复杂的排序需求,比如,对文件所有的含有/RE/的行,按第一列升序,再按第二列降序排,…
诸如此类的排序,利用施瓦茨变换可以事半功倍。
施瓦茨变换的一般格式如下:
1 2 3 |
map { code_that_does_something_with( $_ ) } grep { code_that_selects_from( $_ ) } sort { code_that_compares( $a, $b ) } @array |
这里我举一个实例来说说明这个变化,有如下的的json数据:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
cat dd [{ "createdTime": 11, "versionId": "13a76a74-adc5-4c66-914a-07bb16a486ef" }, { "createdTime": 55, "versionId": "99b26fce-2df8-4364-b13f-3fb89144d64b" }, { "createdTime": 33, "versionId": "4e9ca6a1-1b1d-4586-9ff5-9411330c722d" }, { "createdTime": 44, "versionId": "36859a25-afc4-42c7-bac4-685dc3761c41" }] |
要求根据createdTime的值,取最大createdTime值的versionId,我们利用施瓦茨变换的perl单行实现排序,然后取第一行
1 2 3 4 |
perl -MJSON -000 -e ' map{ print $_->[2],"\n" } sort{ $b->[1] <=> $a->[1] } map{ [$_,$_->{"createdTime"},$_->{"versionId"}]} @{decode_json(<>)}' dd|head 1 |
相对比用perl脚本实现,取两个值,以createdTime为键,构造一个哈希,然后对哈希进行排序。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
#!/bin/env perl use JSON; local $/; open my $FD,'<','dd' or die; my $code = <$FD>; close $FD; my $obj = decode_json($code); my %hash; for(@{$obj}) { $hash{$_->{'createdTime'}}=$_->{'versionId'}; } for (sort keys %hash) { print $hash{$_},"\n"; } |