The London Perl and Raku Workshop takes place on 26th Oct 2024. If your company depends on Perl, please consider sponsoring and/or attending.

NAME

Data::Range::Compare - Framework for calculating range intersections

SYNOPSIS

  use Data::Range::Compare qw(HELPER_CB);

  my %helper=HELPER_CB;

  my @tom;
  my @harry;
  my @sally;

  push @tom,Data::Range::Compare->new(\%helper,0,1);
  push @tom,Data::Range::Compare->new(\%helper,3,7);

  push @harry,Data::Range::Compare->new(\%helper,9,11);

  push @sally,Data::Range::Compare->new(\%helper,6,7);

  my @cmp=(\@tom,\@harry,\@sally);

  my $sub=Data::Range::Compare->range_compare(\%helper,\@cmp);
  while(my @row=$sub->()) {
    my $common_range=
      Data::Range::Compare->get_common_range(\%helper,\@row);
    print "Common Range: $common_range\n";
    my ($tom,$harry,$sally)=@row;
    print "tom:   $tom\n";
    print "harry: $harry\n";
    print "sally: $sally\n";
  }

DESCRIPTION

This package is a universal framework for finding intersections in data representing ranges. The Ranges simply need to be two dimensional.

Data::Range::Compare is not intended to be used directly although it can be. For the most part Data::Range::Compare is intended to be subclassed by other packages.

For a list of more detailed examples, check out the cookbook.

Export list

:KEYS

  key_helper
  key_start
  key_end
  key_generated
  key_missing
  key_data

:HELPER_CB

  HELPER_CB

:HELPER

  add_one
  sub_one
  cmp_values

:SORT

  sort_largest_range_end_first
  sort_largest_range_start_first
  sort_smallest_range_start_first
  sort_smallest_range_end_first
  sort_in_consolidate_order
  sort_in_presentation_order

%helper

%helper is the primary driver for this framework.

Data::Range::Compare relies on %helper to do its internal work. So this section explains how to populate %helper.

  # to import the default %helper functions into your package
  use Data::Range::Compare qw(:HELPER);

  my %helper=(
    add_one=>\&add_one
    sub_one=>\&sub_one
    cmp_values=>\&cmp_values
  );
  • add_one

    This function accepts one argument and returns the next thing. If you are implementing your own add_one, just make sure it returns the correct next value for your data.

      Example:
    
      $helper{add_one}=sub {$_[0] + 1};
      my $next=$helper{add_one}->(1);
      $next==2;
    
      Same as
    
      %helper=HELPER_CB;
    
      Or Write your own
    
      # a-z example
      my @list=('a' .. 'z');
      my $id=-1; 
      my %ids=map { ($_,++$id) } @list;
    
      sub my_add_one {
        my $here=$ids{$_[0]};
        ++$here;
        return 'z' if $#list<$here;
        $list[$here]
      }
    
      $helper{add_one}=\&my_add_one;
      my $next=$helper{add_one}->('a');
      $next eq 'b';
  • sub_one

    This function accepts one argument and returns the next thing. If you are implementing your own sub_one, just make sure it returns the correct previous value for your data.

      Example:
    
      $helper{sub_one}=sub {$_[0] - 1};
      my $next=$helper{sub_one}->(1);
      $next==0;
    
      Same as
    
      %helper=HELPER_CB;
    
      Or Write your own
    
      # a-z example
      my @list=('a' .. 'z');
      my $id=-1; 
      my %ids=map { ($_,++$id) } @list;
    
      sub my_sub_one {
        my $here=$ids{$_[0]};
        --$here;
        return 'z' if 0>$here;
        $list[$here]
      }
    
      $helper{sub_one}=\&my_sub_one;
      my $next=$helper{sub_one}->('a');
      $next eq 'b';
  • cmp_values

    This function accepts 2 arguments and should return one of the following values: 0,-1,1

    Examples:

      $helper{cmp_values}=sub {$_[0] <=> $_[1] };
      my $cmp=$helper{cmp_values}->(0,1);
      $cmp==-1;
    
      Same as
    
      %helper=HELPER_CB;
    
      Or Write your own
    
      # a-z example
      $helper{cmp_values}=sub {$_[0] cmp $_[1] };
      my $cmp=$helper{cmp_values}->(qw(a b));
      $cmp==-1;

OO Methods

This section covers the OO Methods in the package

  • my $range=new Data::Range::Compare(\%helper,0,1);

  • my $range=new Data::Range::Compare(\%helper,0,1,$generated);

  • my $range=new Data::Range::Compare(\%helper,0,1,$generated,$missing);

  • my $range=Data::Range::Compare->new(\%helper,0,1);

  • my $range=Data::Range::Compare->new(\%helper,0,1,$generated);

  • my $range=Data::Range::Compare->new(\%helper,0,1,$generated,$missing);

    This function acts as the general package constructor. "$generated" represents the $range->generated state. "$missing" represents the $range->missing state.

    %helper is what drives the internals of our instance.

  • my $value=$range->helper_cb('add_one',1)

  • my $value=$range->helper_cb('sub_one',1)

  • my $value=$range->helper_cb('cmp_values',1,1)

    Grants access to this range's \%helper.

  • my $range_end=$range->range_end;

    Returns the "thing" that is denoted as the end of this range.

  • my $range_start=$range->range_start;

    Returns the "thing" that is denoted as the start of this range.

  • my $notation=$range->notation;

    Returns a string representing "range_start - range_end". This is the same as print $range.

  • my $helper_hash=$range->helper_hash;

    Gets the \%helper for this instance.

  • if($range->missing) { .. }

    Returns the missing state

  • if($range->generated) { .. }

    Returns the generated state

  • $range->data->{some_lable}='some value'

  • my $value=$range->data->{some_lable};

  • my $hash_ref=$range->data;

    Lets you tag this block with your data.

  • if($range->overlap($another_range);

    Returns true if either of these ranges overlap.

  • my $next_start=$range->next_range_start;

    Gets the thing that represents the start of the next range.

  • my $previous_end=$range->previous_range_end;

    Gets the thing that represents the end of the previous range.

  • my $cmp=$range->cmp_range_start($range_b);

    Wrapper function does the same as the following.

      my $cmp=$range->helper_cb(
        'cmp_values'
        ,$range->range_start
        ,$range_b->range_start
      );
  • my $cmp=$range->cmp_range_end($range_b);

    Wrapper function does the same as the following.

      my $cmp=$range->helper_cb(
        'cmp_values'
        ,$range->range_end
        ,$range_b->range_end
      );
  • if($range_a->contiguous_check($range_b) { ... }

    Returns true if $range_b immediately follows $range_a

  • my $cmp=$range->cmp_ranges($range_b);

    Does an an ascending order style comparison.

  • my $common=Data::Range::Compare->get_common_range(\%helper,\@list)

    Returns a new Data::Range::Compare object representing the intersecting ranges ranges found in \@list.

  • my $range=Data::Range::Compare->get_overlapping_range( \%helper, \@list );

    Returns a new Data::Range::Compare object representing the outer most start and end found in \@list.

  • my $ref=Data::Range::Compare->consolidate_ranges(\%helper,\@list);

    Returns a list reference of sorted and consolidated Data::Range::Compare objects .

  • my $ref=Data::Range::Compare->fill_missing_ranges(\%helper,\@list);

  • my $ref=Data::Range::Compare->fill_missing_ranges(\%helper, \@list, consolidate_ranges=>0);

  • my $ref=Data::Range::Compare->fill_missing_ranges(\%helper, \@list, consolidate_ranges=>1);

    Returns a sorted contiguous list of Data::Range::Compare objects. All objects generated by fill_missing_ranges are created as missing and generated.

    Optional argument consolidate_ranges=>(0||1)

      consolidate_ranges=>1 
        calls Data::Range::Compare->consolidate_ranges(\%helper,\@list)
        before processing ranges
    
      consolidate_ranges=>0 ( Default )
        Skips the consolidate pass
  • my $ref=Data::Range::Compare->range_start_end_fill( \%helper, \@list_of_lists);

    Creates filler ranges ensuring each list of ranges starts and ends with the same value. All ranges created by range_start_end_fill are missing and generated.

  • my $sub=Data::Range::Compare->range_compare( \%helper, \@list_of_lists );

  • my $sub=Data::Range::Compare->range_compare(\%helper, \@list_of_lists, consolidate_ranges=>0);

  • my $sub=Data::Range::Compare->range_compare( \%helper, \@list_of_lists, consolidate_ranges=>1);

    Returns an anonymous function. The function can be used to iterate through the list of lists at intersecting points.

    Optional argument consolidate_ranges>(0||1)

      consolidate_ranges=>1 ( Default )
        calls Data::Range::Compare->consolidate_ranges(\%helper,\@list)
        on each \@list in \@list_of_lists
        before entering the compare process
    
      consolidate_ranges=>0 
        Skips the consolidate pass
  • my ($row,$cols,$next)=Data::Range::Compare->init_compare_row(\%helper, \@list_of_lists);

    This initializes the values for compare_row, producing the first row. See range_compare for a more practical iterator interface.

  • ($row,$cols,$next)=Data::Range::Compare->compare_row( \%helper, \@list_of_lists, $row, $cols ) if $next;

    Used to continue iteration through @list_of_lists while $next;

Sort Methods

This section documents the export-able sort functions. These are low level sort functions and must be used in a call to "sort".

Example:

  @list=sort sort_in_presentation_order @list;
  • @list=sort sort_in_presentation_order @unsorted_list;

    Sorts a list of Data::Range::Compare objects in presentation order.

  • @list=sort sort_in_consolidate_order @unsorted_list;

    Sorts a list of Data::Range::Compare objects in the order required for range consolidation.

  • @list=sort sort_largest_range_end_first @unsorted_list;

    Sorts a list Data::Range::Compare objects by range_end in descending order.

  • @list=sort sort_smallest_range_start_first @unsorted_list;

    Sorts a list Data::Range::Compare objects by range_start in ascending order.

  • @list=sort sort_smallest_range_end_first @unsorted_list;

    Sorts a list Data::Range::Compare objects by range_end in ascending order.

  • @list=sort sort_largest_range_start_first @unsorted_list;

    Sorts a list Data::Range::Compare objects by range_start in descending order.

SEE ALSO

Data::Range::Compare::Cookbook

AUTHOR

Michael Shipper

SourceForge Project

As of version 1.026 the Project has been moved to SourceForge.net

Data Range Compare https://sourceforge.net/projects/data-range-comp/

COPYRIGHT

Copyright 2010 Michael Shipper. All rights reserved.

This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself.