1Array::IntSpan(3)     User Contributed Perl Documentation    Array::IntSpan(3)
2
3
4

NAME

6       Array::IntSpan - Handles arrays of scalars or objects using integer
7       ranges
8

SYNOPSIS

10         use Array::IntSpan;
11
12         my $foo = Array::IntSpan->new([0, 59, 'F'], [60, 69, 'D'], [80, 89, 'B']);
13
14         print "A score of 84% results in a ".$foo->lookup(84).".\n";
15         unless (defined($foo->lookup(70))) {
16           print "The grade for the score 70% is currently undefined.\n";
17         }
18
19         $foo->set_range(70, 79, 'C');
20         print "A score of 75% now results in a ".$foo->lookup(75).".\n";
21
22         $foo->set_range(0, 59, undef);
23         unless (defined($foo->lookup(40))) {
24           print "The grade for the score 40% is now undefined.\n";
25         }
26
27         $foo->set_range(87, 89, 'B+');
28         $foo->set_range(85, 100, 'A');
29         $foo->set_range(100, 1_000_000, 'A+');
30

DESCRIPTION

32       "Array::IntSpan" brings the speed advantages of "Set::IntSpan" (written
33       by Steven McDougall) to arrays.  Uses include manipulating grades,
34       routing tables, or any other situation where you have mutually
35       exclusive ranges of integers that map to given values.
36
37       The new version of "Array::IntSpan" is also able to consolidate the
38       ranges by comparing the adjacent values of the range. If 2 adjacent
39       values are identical, the 2 adjacent ranges are merged.
40

Ranges of objects

42       "Array::IntSpan" can also handle objects instead of scalar values.
43
44       But for the consolidation to work, the payload class must overload the
45       "", "eq" and "==" operators to perform the consolidation comparisons.
46
47       When a get_range method is called to a range of objects, it will return
48       a new range of object referencess. These object references points to
49       the objects stored in the original range. In other words the objects
50       contained in the returned range are not copied.
51
52       Thus if the user calls a methods on the objects contained in the
53       returned range, the method is actually invoked on the objects stored in
54       the original range.
55
56       When a get_range method is called on a range of objects, several things
57       may happen:
58
59       •   The get_range spans empty slots. By default the returned range will
60           skip the empty slots. But the user may provide a callback to create
61           new objects (for instance). See details below.
62
63       •   The get_range splits existing ranges. By default, the split range
64           will contains the same object reference. The user may provide
65           callback to perform the object copy so that the split range will
66           contains different objects. See details below.
67

Ranges specified with integer fields

69       •   "Array::IntSpan::IP" is also provided with the distribution.  It
70           lets you use IP addresses in any of three forms (dotted decimal,
71           network string, and integer) for the indices into the array.  See
72           the POD for that module for more information. See
73           Array::IntSpan::IP for details.
74
75       •   "Array::IntSpan::Fields" is also provided with the distribution. It
76           let you specify an arbitrary specification to handle ranges with
77           strings made of several integer separared by dots (like IP
78           addresses of ANSI SS7 point codes). See Array::IntSpan::Fields for
79           details.
80

METHODS

82   new (...)
83       The "new" method takes an optional list of array elements.  The
84       elements should be in the form "[start_index, end_index, value]".  They
85       should be in sorted order and there should be no overlaps.  The
86       internal method "_check_structure" will be called to verify the data is
87       correct.  If you wish to avoid the performance penalties of checking
88       the structure, you can use "Data::Dumper" to dump an object and use
89       that code to reconstitute it.
90
91   clear
92       Clear the range.
93
94   set_range (start, end, value [, code ref] )
95       This method takes three parameters - the "start_index", the
96       "end_index", and the "value".  If you wish to erase a range, specify
97       "undef" for the "value".  It properly deals with overlapping ranges and
98       will replace existing data as appropriate.  If the new range lies after
99       the last existing range, the method will execute in O(1) time.  If the
100       new range lies within the existing ranges, the method executes in O(n)
101       time, where n is the number of ranges. It does not consolidate
102       contiguous ranges that have the same "value".
103
104       If you have a large number of inserts to do, it would be beneficial to
105       sort them first.  Sorting is O(n lg(n)), and since appending is O(1),
106       that will be considerably faster than the O(n^2) time for inserting n
107       unsorted elements.
108
109       The method returns 0 if there were no overlapping ranges and 1 if there
110       were.
111
112       The optional code ref is called back when an existing range is split.
113       For instance if the original range is "[0,10,$foo_obj]" and set_range
114       is called with "[5,7,$bar_obj']", the callback will be called twice:
115
116        $callback->(0, 4,$foo_obj)
117        $callback->(8,10,$foo_obj)
118
119       It will be the callback responsability to make sure that the range
120       "0-4" and "7-10" holds 2 different objects.
121
122   set( index,  value [, code ref] )
123       Set a single value. This may split an existing range. Actually calls:
124
125        set_range( index, index, value [, code ref] )
126
127   set_range_as_string ( index,  string [, code ref] )
128       Set one one several ranges specified with a string. Ranges are
129       separated by "-".  Several ranges can be specified with commas.
130
131       Example:
132
133         set_range_as_string( '1-10,13, 14-20', 'foo')
134
135       White space are ignored.
136
137   get_range (start, end [, filler | undef , copy_cb [, set_cb]])
138       This method returns a range (actually an Array::IntSpan object) from
139       "start" to "end".
140
141       If "start" and "end" span empty slot in the original range, get_range
142       will skip the empty slots. If a "filler" value is provided, get_range
143       will fill the slots with it.
144
145        original range    : [2-4,X],[7-9,Y],[12-14,Z]
146        get_range(3,8)    : [3-4,X],[7-8,Y]
147        get_range(2,10,f) : [3-4,X],[5-6,f],[7-8,Y]
148
149       If the "filler" parameter is a CODE reference, the filler value will be
150       the one returned by the sub ref. The sub ref is invoked with
151       "(start,end)", i.e. the range of the empty span to fill
152       ("get_range(5,6)" in the example above). When handling object, the sub
153       ref can invoke an object constructor.
154
155       If "start" or "end" split an original range in 2, the default behavior
156       is to copy the value or object ref contained in the original range:
157
158        original range     : [1-4,X]
159        split range        : [1-1,X],[2-2,X],[3-4,X]
160        get_range(2)       : [2-2,X]
161
162       If the original range contains object, this may lead to disapointing
163       results. In the example below the 2 ranges contains references
164       ("obj_a") that points to the same object:
165
166        original range     : [1-4,obj_a]
167        split range        : [1-1,obj_a],[2-2,obj_a],[3-4,obj_a]
168        get_range(2)       : [2-2,obj_a]
169
170       Which means that invoking a method on the object returned by
171       get_range(2) will also be invoked on the range 1-4 of the original
172       range which may not be what you want.
173
174       If "get_range" is invoked with a copy parameter (actually a code
175       reference), the result of this routine will be stored in the split
176       range outside of the get_range:
177
178        original range     : [1-4,X]
179        get_range(2)       : [2-2,X]
180        split range        : [1-1,copy_of_X],[2-2,X],[3-4,copy_of_X]
181
182       When dealing with object, the sub ref should provide a copy of the
183       object:
184
185        original range     : [1-4,obj_a]
186        get_range(2)       : [2-2,obj_a]
187        split range        : [1-1,obj_a1],[2-2,obj_a],[3-4,obj_a2]
188
189       Note that the "obj_a" contained in the "split range" and the "obj_a"
190       contained in the returned range point to the same object.
191
192       The sub ref is invoked with "(start,end,obj_a)" and is expected to
193       return a copy of "obj_a" that will be stored in the split ranges. In
194       the example above, 2 different copies are made: "obj_a1" and "obj_a2".
195
196       Last, a 3rd callback may be defined by the user: the "set_cb". This
197       callback will be used when the range start or end that holds an object
198       changes. In the example above, the "set_cb" will be called this way:
199
200        $obj_a->&$set_cb(2,2) ;
201
202       As a matter of fact, the 3 callback can be used in the same call. In
203       the example below, "get_range" is invoked with 3 subs refs:
204       "\&f,\&cp,\&set":
205
206        original range     : [1-4,obj_a],[7-9,obj_b]
207        get_range(3-8,...) : [3-4,obj_a],[5-6,obj_fill],[7-8,obj_b]
208        split range        : [1-2,obj_a1], [3-4,obj_a],[5-6,obj_fill],
209                             [7-8,obj_b],[9-9,obj_b1]
210
211       To obtain this, get_range will perform the following calls:
212
213        $obj_fill = &f ;
214        $obj_a1 = &cp(5,6,obj_a);
215        &set(3,4,$obj_a) ;
216        $obj_b = &cp(9,9,obj_b) ;
217        &set(7-8,obj_b) ;
218
219   get_range_list
220       In scalar context, returns a list of range in a string like:
221       ""1-5,7,9-11"".
222
223       In list context retunrs a list of list, E.g. " ( [1,5], [7,7], 9,11])".
224
225   lookup( index )
226       This method takes as a single parameter the "index" to look up.  If
227       there is an appropriate range, the method will return the associated
228       value.  Otherwise, it returns "undef".
229
230   get_element( element_number )
231       Returns an array containing the Nth range element:
232
233        ( start, end, value )
234
235   consolidate( [ bottom, top , [ set_cb ]] )
236       This function scans the range from the range index "bottom" to "top"
237       and compare the values held by the adjacent ranges. If the values are
238       identical, the adjacent ranges are merged.
239
240       The comparison is made with the "==" operator. Objects stored in the
241       range must overload the "==" operator. If not, the comparison is made
242       with the standard stringification of an object and the merge never
243       happens.
244
245       If provided, the "set_cb" is invoked on the contained object after 2
246       ranges are merged.
247
248       For instance, if "$obj_a" eq "$obj_b":
249
250        original range is            : [1-4,obj_a],[5-9,obj_b]
251        consolidate(0,1,\&set) yields: [1-9,obj_a]
252
253       And "consolidate" performs this call:
254
255        $set->(1,9,obj_a) ;
256
257       Consolidate the whole range when called without parameters.
258

CONTRIBUTORS

260       •   Mohammad S Anwar <mohammad.anwar@yahoo.com>
261

AUTHORS

263       •   Toby Everett, teverett@alascom.att.com
264
265       •   Dominique Dumont, ddumont@cpan.org
266
267       Copyright (c) 2000 Toby Everett.  Copyright (c) 2003-2004,2014,2020
268       Dominique Dumont.  All rights reserved.  This program is free software.
269
270       This module is distributed under the Artistic 2.0 License. See
271       https://www.perlfoundation.org/artistic-license-20.html
272
273
274
275perl v5.34.0                      2022-01-20                 Array::IntSpan(3)
Impressum