File Coverage

blib/lib/Algorithm/EquivalenceSets.pm
Criterion Covered Total %
statement 34 34 100.0
branch 4 6 66.6
condition n/a
subroutine 6 6 100.0
pod 1 1 100.0
total 45 47 95.7


line stmt bran cond sub pod time code
1 1     1   878 use 5.006;
  1         4  
  1         144  
2 1     1   7 use strict;
  1         2  
  1         31  
3 1     1   6 use warnings;
  1         2  
  1         49  
4              
5             package Algorithm::EquivalenceSets;
6             BEGIN {
7 1     1   29 $Algorithm::EquivalenceSets::VERSION = '1.101420';
8             }
9              
10             # ABSTRACT: Group sets transitively
11 1     1   5 use Exporter qw(import);
  1         1  
  1         452  
12             our @EXPORT = qw(equivalence_sets);
13              
14             sub equivalence_sets {
15 6     6 1 51476 my $item_list = shift;
16 6         9 my $next_group = 1;
17 6         8 my %group; # key = item, value = group this item belongs to
18             my %member; # key = group name, value = list of items in this group
19 6         13 for my $item_def (@$item_list) {
20              
21             # flatten item aliases
22 19 50       30 my @alias = map { ref eq 'ARRAY' ? @$_ : $_ } @$item_def;
  54         161  
23 19         26 my %seen_group;
24              
25             # known groups that these aliases belong to
26 10         28 my @group =
27 54 100       190 grep { !$seen_group{$_}++ }
28 19         27 map { $group{$_} || () } @alias;
29              
30             # unify the groups listed in @group by dissolving them and adding
31             # their members to the aliases, then forming a new group from the
32             # aliases
33 19         26 push @alias, map { @{ $member{$_} } } @group;
  10         11  
  10         37  
34 19         23 my %seen_member;
35 19         26 @alias = grep { !$seen_member{$_}++ } @alias;
  87         218  
36 19         32 delete @member{@group};
37 19         27 my $new_group = $next_group++;
38 19         78 $group{$_} = $new_group for @alias;
39 19         73 $member{$new_group} = \@alias;
40             }
41 6 50       35 wantarray ? values %member : [ values %member ];
42             }
43             1;
44              
45              
46             __END__