Next: Text::Wigwam::Library::System | Previous: Text::Wigwam::Library::Sets | [Table of Contents] | [Text::Wigwam Index] |
Text::Wigwam::Library::Struct #adjoin, #join, #keys, #pop, #push, #reverse, #shift, #sizeof, #sort, #sort_keylist, #key_sort, #split, #substr, #unshift, #values
This library provides directives that mostly deal with data structures.
The directives within this library can be imported into specific branches of
the directive tree (which transcends from Text::Wigwam::Directives
) via
plug-ins or modules using one of the following techniques.
package Text::Wigwam::Directives::some::arbitrary::branch; # import everything use Text::Wigwam::Library::Struct qw/:all/; package Text::Wigwam::Directives::another::arbitrary::branch; # import selectively use Text::Wigwam::Library::Struct qw( :adjoin :join :keys :pop :push :reverse :shift :sizeof :sort :sort_keylist :key_sort :split :substr :unshift :values );
Passes each key/value pair of hash|array through macro and joins the results of each call with string.
[!! #adjoin ", " %< one 1, two 2, three 3 > { #argv 0 '=' #argv 1 } /* output (note that the order is arbitrary when adjoining hashes): two=2, one=1, three=3 */ !!]
If we omit the optional macro argument, or if the macro returns a null string, only the hash value is adjoined.
[!! #adjoin ", " %< one 1, two 2, three 3 >; /* output (arbitrary order): 3, 1, 2 */ !!]
When adjoining arrays, the key represents a given value's index position within the array.
[!! #adjoin "; " < zero one two three four > { #argv 0 '=' #argv 1 } /* output: 0=zero; 1=one; 2=two; 3=three; 4=four */ !!]
If the optional macro argument is omitted, or if the macro returns a null string value, the array values are simply adjoined.
[!! #adjoin "; " < zero one two three four >; /* output: zero; one; two; three; four */ !!]
The macro can be defined in advance and simply passed to the #adjoin directive when required.
[!! #macro jmacro { #parameters < name value > name '=' value } #adjoin ", " %< one 1, two 2, three 3 > jmacro /* output (the order is arbitrary): three=3, one=1, two=2 */ !!]
Returns a string made up of all elements of array, delimited by string.
[!! #join ", " ( "a" "c" "e" "g" ) /* output: a, c, e, g */ !!]
If a hash is provided, #keys
returns an array containing all keys found in
hash.
[!! #join ", " #keys %< key1 val1, key2 val2 > /* output (the order will vary): key1, key2 */ !!]
If an array is passed, #keys
will return an array containing the indices of array.
[!! #join ", " #keys ( "a" "b" "c" "d" ) /* output: 0, 1, 2, 3 */ !!]
Removes the last element of array and returns its value. Consequently, array's size is decreased by one element.
[!! #define array ( 1 2 3 4 5 ) #while array #pop array /* output: 54321 */ !!]
Adds an element to the end of array and sets its value to arg. Consequently, array's size
is increased by one element. #push
does not return a value.
[!! #define array ( 1 2 3 ) #push array 4 #join ", " array /* output: 1, 2, 3, 4 */ !!]
If an array is provided, #reverse returns a copy of the elements contained within array in reverse order. array remains unaltered.
[!! #join ", " #reverse ( 1 2 3 4 5 ) /* output: 5, 4, 3, 2, 1 */ !!]
If a hash is provided, #reverse returns a hash whose key/value pairs are reversed, with respect to hash. hash remains unaltered.
[!! #join ", " #keys #reverse %( 1 2 3 4 5 6 ) /* output (order will vary): 6, 4, 2 */ !!]
Removes the first element of array and returns its value. Consequently, the size of the array is decreased by one element, and all remaining elements within the array shift down one position.
[!! #define array ( 1 2 3 4 5 ) #while array #shift array /* output: 12345 */ !!]
Returns the number of elements in arg, where arg is an array; numbers of keys where arg is a hash; or number of characters where arg is a string or scalar reference.
hash size: [!! #sizeof %< a b c d > !!] (number of keys) array size: [!! #sizeof < a b c d > !!] (number of elements) scalar size: [!! #sizeof "abcd" !!] (number of characters) macro size: [!! #sizeof #expr {} !!] (number of tokens) [!! /* output: hash size: 2 (number of keys) array size: 4 (number of elements) scalar size: 4 (number of characters) macro size: 2 (number of tokens) */ !!]
Returns a sorted copy of array elements taken from array, and array remains unaltered.
[!! #join ", " #sort ( 02 6 1 7 10 "a" 4 "b" ) /* output: 1, 02, 4, 6, 7, 10, a, b */ !!]
As demonstrated in the previous example, the #sort
directive takes true
numeric values into account when sorting.
Returns an array of keys, supplied by the key-list argument, which are sorted according to the pattern-list, which is merely an ordered list of variables from whose values the keys are to be sorted. Each element of the pattern-list array represents a level of criteria to sort upon. Should the first element match two given entries, the second element will then be used and so on until a basis for sorting is found, or until all pattern criteria is exhausted, in which case the keys themselves serve as the final criteria.
The pattern-list elements take the following form:
+path.to.keys.[:key].path:2.values
Optionally, the first character indicates the sort order: '+' indicates ascending; '-' indicates descending. If omitted, ascending is implied. The :key global represents the position within the path name where the keys will be inserted during the sort process.
The #key_sort
directive is handy for sorting records which are stored
in a nested hash complex, as the following examples demonstrate. First, we'll
set up a mock inventory database...
[!! #define inventory %< 100001 %< onhand 10 price 19.95 item "Putty" > 100002 %< onhand 10 price 19.95 item "Puppy" > 100003 %< onhand 13 price 21.95 item "Clock" > 100004 %< onhand 33 price 22.95 item "Pistol" > 100005 %< onhand 12 price 14.99 item "Camera" > 100006 %< onhand 21 price 16.99 item "Toaster" > > !!]
In Perl, this data structure would look something like this...
$inventory = { 100001 => { onhand => 30, price => "19.95", item => "Putty" }, 100002 => { onhand => 10, price => "19.95", item => "Puppy" }, ... };
First, let's dump all of the records sorted by item field.
[!! #foreach thing #key_sort inventory`keys ( "+inventory.[:key].item" ) !!> [!!thing!!] Qty: [!!inventory.[thing].onhand!!], [!~ "$" inventory.[thing].price!!] ea. [!!inventory.[thing].item!!] <!! /* output: 100005 Qty: 12, $14.99 ea. Camera 100003 Qty: 13, $21.95 ea. Clock 100004 Qty: 33, $22.95 ea. Pistol 100002 Qty: 10, $19.95 ea. Puppy 100001 Qty: 10, $19.95 ea. Putty 100006 Qty: 21, $16.99 ea. Toaster */ !!]
Next, let's list the items by quantity on-hand, beginning with the highest volume first.
[!! #foreach thing #key_sort inventory`keys ( "-inventory.[:key].onhand" )!!> [!!thing!!] Qty: [!!inventory.[thing].onhand!!], [!~ "$" inventory.[thing].price!!] ea. [!!inventory.[thing].item!!] <!! /* output: 100004 Qty: 33, $22.95 ea. Pistol 100006 Qty: 21, $16.99 ea. Toaster 100003 Qty: 13, $21.95 ea. Clock 100005 Qty: 12, $14.99 ea. Camera 100002 Qty: 10, $19.95 ea. Puppy 100001 Qty: 10, $19.95 ea. Putty */ !!]
Finally, we'll sort the records by price, then by quantity on-hand in descending order, then by item name. Also, just because we can, we'll leave out the '+' this time on the criteria which we want sorted in ascending order.
[!! #foreach thing #key_sort inventory`keys ( "inventory.[:key].price" "-inventory.[:key].onhand" "inventory.[:key].item" ) !!> [!!thing!!] Qty: [!!inventory.[thing].onhand!!], [!~ "$" inventory.[thing].price!!] ea. [!!inventory.[thing].item!!] <!~ /* output: 100005 Qty: 12, $14.99 ea. Camera 100006 Qty: 21, $16.99 ea. Toaster 100002 Qty: 10, $19.95 ea. Puppy 100001 Qty: 10, $19.95 ea. Putty 100003 Qty: 13, $21.95 ea. Clock 100004 Qty: 33, $22.95 ea. Pistol */ !!]
Works like #key_sort, but the pattern-list elements take the following form:
+path.to.keys.*.path:2.values
The asterisk character represents the position within the path name where the keys will be inserted during the sort process. This format was abandoned in favor of the globals-based format as implemented in the #key_sort directive.
Returns an array of elements made up of chunks of string separated by occurrences of separator.
[!! #define array #split ":" "foo:bar:quux:bazz" #join ", " array /* output: foo, bar, quux, bazz */ !!]
Returns information in string after the numerically declared index which signifies the byte with which you wish to start the extraction. The amount of data returned will be limited to num bytes.
[!! #substr "abcdefghijkl" 7 2 /* output: hi */ !!]
Inserts arg as the first element of array, thereby increasing the size
of the array by one element, and moving all previously existing elements
within the array up one position. #unshift
does not return a value.
[!! #define array ( 1 2 3 ) #unshift array 4 #join ", " array /* output: 4, 1, 2, 3 */ !!]
Returns an array of values found in hash.
[!! #join ", " #values #hash ( "key1" "val1" "key2" "val2" ) /* output (order will vary): val1, val2 */ !!]