Algorithm-Accounting

 view release on metacpan or  search on metacpan

lib/Algorithm/Accounting.pm  view on Meta::CPAN

    my @index = $self->position_of($self->fields,$groups->[$i]);
    for my $row (@$data) {
      my $permutor = Algorithm::Accounting::Array::Iterator::LOL->new([@$row[@index]]);
      my %exclude;
      while(my $permutation = $permutor->getNext) {
 	my @_row = map {(ref($_) ? $_->[0] : $_)||''} @$permutation;
 	my $__row = freeze(@_row);
 	# One value-tuple would shows only one time,
 	# So it's excluded upon extra permutations.
 	unless($exclude{$__row}) {
 	  $gocc->[$i]->{freeze(@_row)}++;
 	  $exclude{$__row}++;
 	}
      }
    }
  }
  $self->group_occurrence($gocc);
}

sub update_single_field {
  my $data = shift;
  my $aocc = $self->occurrence_array;
  my $hocc = $self->occurrence_hash;
  my $fields = $self->fields;
  for my $i (0..@$fields-1) {
    my $occ = $aocc->[$i] || {};
    for(@$data) {
      last unless exists $_->[$i];
      if('ARRAY' eq ref($_->[$i])) {
	for my $v (@{$_->[$i]}) {$occ->{$v}++}
      } else {
        $occ->{$_->[$i]}++;
      }
    }
    $aocc->[$i] = $occ;
    $hocc->{$fields->[$i]} = $occ;
  }
  $self->occurrence_array($aocc);
  $self->occurrence_hash($hocc);
}

# Find the position of wanted values in an array
sub position_of {
  my ($arr,$wanted) = @_;
  my @index;
  for my $w (@$wanted) {
    for my $i (0..@$arr-1) {
      push @index,$i if($arr->[$i] eq $w);
    }
  }
  return @index;
}

package Algorithm::Accounting::Array::Iterator::LOL;
use Array::Iterator::Reusable;
use Clone qw(clone);

sub new {
  my $class = $self;
  $self = {};
  bless $self,$class;
  my $lol = shift;
  my @lolp; # list of Array::Iterator::Reusable
  for (@$lol) {
     if(ref($_)) {
       push @lolp, Array::Iterator::Reusable->new($_);
     } else {
       push @lolp, Array::Iterator::Reusable->new([$_]);
     }
  }
  $self->{lol}  = $lol;
  $self->{lolp} = \@lolp ;
  $self->reset();
  return $self;
}

sub reset {
  $_->reset for @{$self->{lolp}};
  my @lov;
  push @lov, $self->{lolp}->[0]->peek;
  for my $i (1..@{$self->{lolp}}-1) {
    push @lov,$self->{lolp}->[$i]->getNext;
  }
  $self->{lov} = \@lov;
  return $self;
}

sub get_next {
  my $method = shift;
  my $reset = 0;
  my $nlov  = clone($self->{lov});
  for my $i (0..@{$self->{lolp}}-1) {
    if($self->{lolp}->[$i]->hasNext) {
      $nlov->[$i] = $self->{lolp}->[$i]->$method;
      last;
    } else {
      my $_index;
      $_index= $self->{lol}->[$i]->{_current_index}
	if($method eq 'peek');

      $reset++;
      $self->{lolp}->[$i]->reset;
      $nlov->[$i] = $self->{lolp}->[$i]->getNext || '(DUMMY)';

      $self->{lol}->[$i]->{_current_index} = $_index
	if($method eq 'peek');
    }
  }
  return if($reset == @{$self->{lolp}});
  $self->{lov} = $nlov if($method eq 'getNext');
  return $nlov;
}

sub peek { $self->get_next('peek') }
sub next { $self->get_next('getNext') }
sub getNext { $self->get_next('getNext') }

__END__

=head1 NAME



( run in 0.333 second using v1.01-cache-2.11-cpan-e93a5daba3e )