File Coverage

blib/lib/Catmandu/Fix/sort_field.pm
Criterion Covered Total %
statement 46 48 95.8
branch 18 20 90.0
condition 2 3 66.6
subroutine 8 8 100.0
pod n/a
total 74 79 93.6


line stmt bran cond sub pod time code
1              
2             use Catmandu::Sane;
3 1     1   92918  
  1         3  
  1         6  
4             our $VERSION = '1.2019';
5              
6             use List::MoreUtils qw(uniq);
7 1     1   508 use Catmandu::Util::Path qw(as_path);
  1         8090  
  1         7  
8 1     1   1293 use Moo;
  1         2  
  1         44  
9 1     1   6 use namespace::clean;
  1         1  
  1         6  
10 1     1   291 use Catmandu::Fix::Has;
  1         2  
  1         3  
11 1     1   655  
  1         2  
  1         4  
12             with 'Catmandu::Fix::Builder';
13              
14             has path => (fix_arg => 1);
15             has uniq => (fix_opt => 1);
16             has reverse => (fix_opt => 1);
17             has numeric => (fix_opt => 1);
18             has undef_position => (fix_opt => 1, default => sub {'last'});
19              
20             my ($self) = @_;
21             my $uniq = $self->uniq;
22 12     12   78 my $reverse = $self->reverse;
23 12         19 my $numeric = $self->numeric;
24 12         19 my $undef_position = $self->undef_position;
25 12         18 as_path($self->path)->updater(
26 12         23 if_array_ref => sub {
27             my $val = $_[0];
28              
29 12     12   17 #filter out undef
30             my $undefs = [grep {!defined($_)} @$val];
31             $val = [grep {defined($_)} @$val];
32 12         24  
  60         97  
33 12         16 #uniq
  60         83  
34             if ($uniq) {
35             $val = [uniq(@$val)];
36 12 100       25 }
37 6         59  
38             #sort
39             if ($reverse && $numeric) {
40             $val = [sort {$b <=> $a} @$val];
41 12 50 66     37 }
    100          
    100          
42 0         0 elsif ($numeric) {
  0         0  
43             $val = [sort {$a <=> $b} @$val];
44             }
45 1         3 elsif ($reverse) {
  3         6  
46             $val = [sort {$b cmp $a} @$val];
47             }
48 1         4 else {
  1         3  
49             $val = [sort {$a cmp $b} @$val];
50             }
51 10         32  
  32         53  
52             #insert undef at the end
53             if ($undef_position eq 'first') {
54             if ($uniq) {
55 12 100       32 unshift @$val, undef if @$undefs;
    100          
56 2 100       5 }
57 1 50       4 else {
58             unshift @$val, @$undefs;
59             }
60 1         2 }
61             elsif ($undef_position eq 'last') {
62             if ($uniq) {
63             push @$val, undef if @$undefs;
64 8 100       12 }
65 4 100       10 else {
66             push @$val, @$undefs;
67             }
68 4         7 }
69              
70             $val;
71             }
72 12         205 );
73             }
74 12         37  
75             1;
76              
77              
78             =pod
79              
80             =head1 NAME
81              
82             Catmandu::Fix::sort_field - sort the values of an array
83              
84             =head1 SYNOPSIS
85              
86             # e.g. tags => ["foo", "bar","bar"]
87             sort_field(tags) # tags => ["bar","bar","foo"]
88             sort_field(tags, uniq: 1) # tags => ["bar","foo"]
89             sort_field(tags, uniq: 1, reverse: 1) # tags => ["foo","bar"]
90             # e.g. nums => [ 100, 1 , 10]
91             sort_field(nums, numeric: 1) # nums => [ 1, 10, 100]
92              
93             #push undefined values to the end of the list (default)
94             #beware: reverse has no effect on this!
95             sort_field(tags,undef_position: last)
96              
97             #push undefined values to the beginning of the list
98             #beware: reverse has no effect on this!
99             sort_field(tags,undef_position: first)
100              
101             #remove undefined values from the list
102             sort_field(tags,undef_position: delete)
103              
104             =head1 SEE ALSO
105              
106             L<Catmandu::Fix>
107              
108             =cut