line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
1
|
|
|
1
|
|
663
|
use strict; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
28
|
|
2
|
1
|
|
|
1
|
|
5
|
use warnings; |
|
1
|
|
|
|
|
1
|
|
|
1
|
|
|
|
|
40
|
|
3
|
|
|
|
|
|
|
package Hash::Squash; |
4
|
|
|
|
|
|
|
# ABSTRACT: Remove numbered keys from a nested hash/array |
5
|
|
|
|
|
|
|
|
6
|
1
|
|
|
1
|
|
721
|
use parent 'Exporter'; |
|
1
|
|
|
|
|
254
|
|
|
1
|
|
|
|
|
5
|
|
7
|
1
|
|
|
1
|
|
43
|
use List::Util qw/max/; |
|
1
|
|
|
|
|
1
|
|
|
1
|
|
|
|
|
92
|
|
8
|
|
|
|
|
|
|
|
9
|
1
|
|
|
1
|
|
840
|
use version; our $VERSION = version->declare("v0.0.4"); |
|
1
|
|
|
|
|
2059
|
|
|
1
|
|
|
|
|
7
|
|
10
|
|
|
|
|
|
|
|
11
|
|
|
|
|
|
|
our @EXPORT_OK = qw(squash unnumber); |
12
|
|
|
|
|
|
|
|
13
|
2
|
|
|
2
|
1
|
4421
|
sub squash { _squash(shift) } |
14
|
1
|
|
|
1
|
1
|
2382
|
sub unnumber { _squash(shift, { keep_empty => 1 }) } |
15
|
|
|
|
|
|
|
|
16
|
|
|
|
|
|
|
sub _squash { |
17
|
124
|
|
|
124
|
|
133
|
my ($obj, $arg) = @_; |
18
|
124
|
100
|
|
|
|
265
|
return $obj unless ref $obj; |
19
|
|
|
|
|
|
|
|
20
|
31
|
|
|
|
|
62
|
$obj = _squash_hash($obj, $arg); |
21
|
31
|
|
|
|
|
53
|
$obj = _squash_array($obj, $arg); |
22
|
|
|
|
|
|
|
|
23
|
31
|
|
|
|
|
99
|
return $obj; |
24
|
|
|
|
|
|
|
} |
25
|
|
|
|
|
|
|
|
26
|
|
|
|
|
|
|
sub _squash_hash { |
27
|
31
|
|
|
31
|
|
29
|
my ($obj, $arg) = @_; |
28
|
31
|
100
|
|
|
|
59
|
return $obj if ref $obj ne 'HASH'; |
29
|
|
|
|
|
|
|
|
30
|
24
|
|
|
|
|
48
|
EMPTY_HASH: { |
31
|
24
|
100
|
|
|
|
22
|
last EMPTY_HASH if %{$obj}; |
|
24
|
|
|
|
|
30
|
|
32
|
2
|
100
|
|
|
|
7
|
return (undef) unless exists $arg->{keep_empty}; |
33
|
1
|
50
|
|
|
|
3
|
return (undef) unless $arg->{keep_empty}; |
34
|
1
|
|
|
|
|
3
|
return +{}; |
35
|
|
|
|
|
|
|
} |
36
|
|
|
|
|
|
|
|
37
|
22
|
|
|
|
|
22
|
my @keys = keys %{$obj}; |
|
22
|
|
|
|
|
61
|
|
38
|
|
|
|
|
|
|
|
39
|
69
|
|
|
|
|
144
|
CONTAINS_NON_NUMERIC_KEYS: { |
40
|
22
|
100
|
|
|
|
27
|
last CONTAINS_NON_NUMERIC_KEYS unless grep {/\D/} @keys; |
|
22
|
|
|
|
|
22
|
|
41
|
10
|
|
|
|
|
10
|
my %hash = map { $_ => _squash($obj->{$_}, $arg) } @keys; |
|
28
|
|
|
|
|
63
|
|
42
|
10
|
|
|
|
|
26
|
return \%hash; |
43
|
|
|
|
|
|
|
} |
44
|
|
|
|
|
|
|
|
45
|
12
|
|
100
|
|
|
62
|
my $max = max(@keys) || 0; |
46
|
|
|
|
|
|
|
|
47
|
12
|
|
|
|
|
13
|
my @ar; |
48
|
12
|
|
|
|
|
14
|
for my $i (0 .. $max) { |
49
|
|
|
|
|
|
|
# |
50
|
|
|
|
|
|
|
# Some numbered keys might be partially discreated |
51
|
|
|
|
|
|
|
# |
52
|
44
|
100
|
|
|
|
97
|
push @ar, exists $obj->{$i} ? _squash($obj->{$i}, $arg) : (undef); |
53
|
|
|
|
|
|
|
} |
54
|
|
|
|
|
|
|
|
55
|
12
|
|
|
|
|
30
|
return \@ar; |
56
|
|
|
|
|
|
|
} |
57
|
|
|
|
|
|
|
|
58
|
|
|
|
|
|
|
sub _squash_array { |
59
|
31
|
|
|
31
|
|
36
|
my ($obj, $arg) = @_; |
60
|
31
|
100
|
|
|
|
65
|
return $obj if ref $obj ne 'ARRAY'; |
61
|
|
|
|
|
|
|
|
62
|
19
|
100
|
|
|
|
33
|
my $keep_empty = exists $arg->{keep_empty} ? $arg->{keep_empty} : (); |
63
|
|
|
|
|
|
|
|
64
|
19
|
|
|
|
|
42
|
EMPTY_ARRAY: { |
65
|
19
|
100
|
|
|
|
18
|
last EMPTY_ARRAY if @{$obj} != 0; |
|
19
|
|
|
|
|
17
|
|
66
|
2
|
100
|
|
|
|
19
|
return (undef) unless $keep_empty; |
67
|
1
|
|
|
|
|
3
|
return []; |
68
|
|
|
|
|
|
|
} |
69
|
|
|
|
|
|
|
|
70
|
|
|
|
|
|
|
SINGLE_ELEMENT: { |
71
|
17
|
100
|
|
|
|
19
|
last SINGLE_ELEMENT if @{$obj} != 1; |
|
17
|
|
|
|
|
11
|
|
|
17
|
|
|
|
|
41
|
|
72
|
7
|
100
|
|
|
|
12
|
last SINGLE_ELEMENT if $keep_empty; |
73
|
4
|
|
|
|
|
12
|
return _squash($obj->[0]); |
74
|
|
|
|
|
|
|
} |
75
|
|
|
|
|
|
|
|
76
|
13
|
|
|
|
|
14
|
my @array = map { _squash($_, $arg) } @{$obj}; |
|
48
|
|
|
|
|
61
|
|
|
13
|
|
|
|
|
17
|
|
77
|
|
|
|
|
|
|
|
78
|
13
|
|
|
|
|
27
|
return \@array; |
79
|
|
|
|
|
|
|
} |
80
|
|
|
|
|
|
|
|
81
|
|
|
|
|
|
|
1; |
82
|
|
|
|
|
|
|
__END__ |