/* * $Id$ */ /* * The following parts are Copyright of the individual authors. * www - http://harbour-project.org * * Copyright 1999 Chen Kedem * Documentation for: ASORT() * * Copyright 1999 Luiz Rafael Culik * Documentation for: ARRAY(), AADD(), ACLONE(), ACOPY(), ASIZE(), * ATAIL(), AINS(), ADEL(), AFILL(), ASCAN(), AEVAL() * * See COPYING for licensing terms. * */ /* $DOC$ * $TEMPLATE$ * Function * $NAME$ * ARRAY() * $CATEGORY$ * API * $SUBCATEGORY$ * Array * $ONELINER$ * Create an uninitialized array of specified length * $SYNTAX$ * ARRAY( [, ...] ) --> aArray * $ARGUMENTS$ * is the number of elements in the specified dimension. * $RETURNS$ * an array of specified dimensions. * $DESCRIPTION$ * This function returns an uninitialized array with the length of * . * * Nested arrays are uninitialized within the same array * pointer reference if additional parameters are specified. * * Establishing a memory variable with the same name as the array may * destroy the original array and release the entire contents of the * array. This depends, of course, on the data storage type of either * the array or the variable with the same name as the array. * $EXAMPLES$ * PROCEDURE Main() * LOCAL aArray := Array( 10 ) * LOCAL x * FOR x := 1 TO Len( aArray ) * aArray[ x ] := Array( x ) * NEXT * // Result is: { { NIL }, { NIL, NIL }, ... } * RETURN * $STATUS$ * R * $COMPLIANCE$ * C(array) * $FILES$ * Library is vm * $SEEALSO$ * AADD(),ADEL(),AFILL(),AINS() * $END$ */ /* $DOC$ * $TEMPLATE$ * Function * $NAME$ * AADD() * $CATEGORY$ * API * $SUBCATEGORY$ * Array * $ONELINER$ * Dynamically add an element to an array * $SYNTAX$ * AADD([, ]) --> Value * $ARGUMENTS$ * The name of an array * * Element to add to array * $RETURNS$ * if specified , will return , otherwise this * function returns a NIL value. * $DESCRIPTION$ * This function dynamically increases the length of the array named * by one element and stores the value of to that * newly created element. * * may be an array reference pointer, which in turn may be * stored to an array's subscript position. * $EXAMPLES$ * LOCAL aArray := {} * LOCAL x * AAdd( aArray, 10 ) * FOR x := 1 TO 10 * AAdd( aArray, x ) * NEXT * // Result is: { 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 } * $STATUS$ * R * $COMPLIANCE$ * C * $FILES$ * Library is vm * $SEEALSO$ * AINS(),ASIZE() * $END$ */ /* $DOC$ * $TEMPLATE$ * Function * $NAME$ * ASIZE() * $CATEGORY$ * API * $SUBCATEGORY$ * Array * $ONELINER$ * Adjust the size of an array * $SYNTAX$ * ASIZE(, ) --> aTarget * $ARGUMENTS$ * Name of array to be dynamically altered * * Numeric value representing the new size of * $RETURNS$ * an array pointer reference to . * $DESCRIPTION$ * This function will dynamically increase or decrease the size of * by adjusting the length of the array to subscript * positions. * * If the length of the array is shortened, those former * subscript positions are lost. If the length of the array is * lengthened a NIL value is assigned to the new subscript position. * $EXAMPLES$ * LOCAL aArray := { 1 } // Result: aArray is { 1 } * ASize( aArray, 3 ) // Result: aArray is { 1, NIL, NIL } * ASize( aArray, 1 ) // Result: aArray is { 1 } * $STATUS$ * R * $COMPLIANCE$ * If HB_COMPAT_C53 is defined, the function generates an Error, * else it will return the array itself. * $FILES$ * Library is vm * $SEEALSO$ * AADD(),ADEL(),AFILL(),AINS() * $END$ */ /* $DOC$ * $TEMPLATE$ * Function * $NAME$ * ATAIL() * $CATEGORY$ * API * $SUBCATEGORY$ * Array * $ONELINER$ * Returns the rightmost element of an array * $SYNTAX$ * ATAIL( ) --> Element * $ARGUMENTS$ * is the array. * $RETURNS$ * the expression of the last element in the array. * $DESCRIPTION$ * This function return the value of the last element in the array * named . This function does not alter the size of the * array or any of the subscript values. * $EXAMPLES$ * LOCAL aArray := { "Harbour", "is", "Supreme", "Power" } * ? ATail( aArray ) // Result is "Power" * $STATUS$ * R * $COMPLIANCE$ * C * $FILES$ * Library is vm * $SEEALSO$ * LEN(),ARRAY(),ASIZE(),AADD() * $END$ */ /* $DOC$ * $TEMPLATE$ * Function * $NAME$ * AINS() * $CATEGORY$ * API * $SUBCATEGORY$ * Array * $ONELINER$ * Insert a NIL value at an array subscript position. * $SYNTAX$ * AINS( , ) --> aTarget * $ARGUMENTS$ * Array name. * * Subscript position in * $RETURNS$ * an array pointer reference. * $DESCRIPTION$ * This function inserts a NIL value in the array named * at the th position. * * All array elements starting with the th position will be * shifted down one subscript position in the array list and the * last item in the array will be removed completely. In other words, * if an array element were to be inserted at the fifth subscript * position, the element previously in the fifth position would now * be located at the sixth position. The length of the array * will remain unchanged. * $EXAMPLES$ * LOCAL aArray := { "Harbour", "is", "Power!", "!!!" } * AIns( aArray, 4 ) * $STATUS$ * R * $COMPLIANCE$ * C * $FILES$ * Library is vm * $SEEALSO$ * AADD(),ACOPY(),ADEL(),AEVAL(),AFILL(),ASIZE() * $END$ */ /* $DOC$ * $TEMPLATE$ * Function * $NAME$ * ADEL() * $CATEGORY$ * API * $SUBCATEGORY$ * Array * $ONELINER$ * Delete an element form an array. * $SYNTAX$ * ADEL(, ) --> aTarget * $ARGUMENTS$ * Name of array from which an element is to be removed. * * Subscript of the element to be removed. * $RETURNS$ * an array pointer reference. * $DESCRIPTION$ * This function deletes the element found at subscript position * in the array . All elements in the array below the * given subscript position will move up one position in the * array. In other words, what was formerly the sixth subscript position * will become the fifth subscript position. The length of the array * will remain unchanged,as the last element in the array will * become a NIL data type. * $EXAMPLES$ * LOCAL aArray := { "Harbour", "is", "Power" } * ADel( aArray, 2 ) // Result: aArray is { "Harbour", "Power" } * $STATUS$ * R * $COMPLIANCE$ * C * $FILES$ * Library is vm * $SEEALSO$ * ACOPY(),AINS(),AFILL() * $END$ */ /* $DOC$ * $TEMPLATE$ * Function * $NAME$ * AFILL() * $CATEGORY$ * API * $SUBCATEGORY$ * Array * $ONELINER$ * Fill an array with a specified value * $SYNTAX$ * AFILL( , , [], [] ) --> aTarget * $ARGUMENTS$ * Name of array to be filled. * * Expression to be globally filled in * * Subscript starting position * * Number of subscript to be filled * $RETURNS$ * an array pointer. * $DESCRIPTION$ * This function will fill each element of an array named with * the value . If specified, denotes the beginning * element to be filled and the array elements will continue to be * filled for positions. If Not specified, the value of * will be 1, and the value of will be the value * of LEN(); thus, all subscript positions in the array * will be filled with the value of . * * This function will work on only a single dimension of . * If there are array pointer references within a subscript , * those values will be lost, since this function will overwrite those * values with new values. * $EXAMPLES$ * LOCAL aTest := { NIL, 0, 1, 2 } * AFill( aTest, 5 ) * $STATUS$ * R * $COMPLIANCE$ * C * $FILES$ * Library is vm * $SEEALSO$ * AADD(),AEVAL(),DBSTRUCT(),DIRECTORY() * $END$ */ /* $DOC$ * $TEMPLATE$ * Function * $NAME$ * ASCAN() * $CATEGORY$ * API * $SUBCATEGORY$ * Array * $ONELINER$ * Scan array elements for a specified condition * $SYNTAX$ * ASCAN( , , [], [] ) --> nStoppedAt * $ARGUMENTS$ * Array to be scanned. * * Expression to search for in * * Beginning subscript position at which to start the search. * * Number of elements to scan with . * $RETURNS$ * A numeric value of subscript position where * was found, or 0 if is not found. * $DESCRIPTION$ * This function scan the content of array named for the * value of . The return value is the position in the array * in which was found. If it was not found, the * return value will be 0. * * If specified, the beginning subscript position at which to start * scanning may be set with the value passed as . The default * is 1. * * If specified, the number of array elements to scan may be set with * the value passed as . The default is the number of elements * in the array . * * If is a code block, the operation of the function is * slightly different. Each array subscript pointer reference is * passed to the code block to be evaluated. The scanning routine * will continue until the value obtained from the code block is a * logical true (.T.) or until the end of the array has been reached. * $EXAMPLES$ * LOCAL aDir := Directory( "*.prg" ) * AScan( aDir,,, {| x, y | x[ 1 ] := "test.prg" } ) * $STATUS$ * R * $COMPLIANCE$ * This function is not CA-Cl*pper compatible. CA-Cl*pper ASCAN() is affected by the SET EXACT ON/OFF Condition * $FILES$ * Library is vm * $SEEALSO$ * AEVAL() * $END$ */ /* $DOC$ * $TEMPLATE$ * Function * $NAME$ * AEVAL() * $CATEGORY$ * API * $SUBCATEGORY$ * Array * $ONELINER$ * Evaluates the subscript element of an array * $SYNTAX$ * AEVAL(, , [], []) --> aArray * $ARGUMENTS$ * Is the array to be evaluated. * * Is a code block to evaluate for each element processed. * * The beginning array element index to evaluate. * * The number of elements to process. * $RETURNS$ * an array pointer reference. * $DESCRIPTION$ * This function will evaluate and process the subscript elements * in . A code block passed as defines the operation * to be executed on each element of the array. All elements in * will be evaluated unless specified by a beginning subscript position * in for elements. * * Two parameters are passed to the code block . The individual * elements in an array are the first parameter and the subscript position * is the second. * * AEVAL() does not replace a FOR...NEXT loop for processing arrays. If * an array is an autonomous unit, AEVAL() is appropriate. If the array * is to be altered or if elements are to be reevaluated, a FOR...NEXT * loop is more appropriate. * $STATUS$ * R * $COMPLIANCE$ * C * $FILES$ * Library is vm * $SEEALSO$ * EVAL(),DBEVAL() * $END$ */ /* $DOC$ * $TEMPLATE$ * Function * $NAME$ * ACOPY() * $CATEGORY$ * API * $SUBCATEGORY$ * Array * $ONELINER$ * Copy elements from one array to another * $SYNTAX$ * ACOPY( , , [], [], [] ) --> aTarget * $ARGUMENTS$ * is the array to copy elements from. * * is the array to copy elements to. * * is the beginning subscript position to copy from * * the number of subscript elements to copy from . * * the starting subscript position in to copy * elements to. * $RETURNS$ * an array pointer reference * $DESCRIPTION$ * This function copies array elements from to . * * is the beginning element to be copied from ; * the default is 1. * * is the number of elements to be copied from ; * the default is the entire array. * * is the subscript number in the target array,, * to which array elements are to be copied; the default is 1 * * This function will copy all data types in to . * * If an array element in is a pointer reference to another * array, that array pointer will be copied to ; not all * subdimensions will be copied from one array to the next. This must * be accomplished via the ACLONE() function. * * Note: * If array is larger then , array elements will * start copying at and continue copying until the end * of array is reached. The ACOPY() function doesn't append * subscript positions to the target array, the size of the target * array remains constant. * $EXAMPLES$ * LOCAL nCount := 2, nStart := 1, aOne, aTwo * aOne := { "HARBOUR", " is ", "POWER"} * aTwo := { "CLIPPER", " was ", "POWER"} * ACopy( aOne, aTwo, nStart, nCount ) * $STATUS$ * R * $COMPLIANCE$ * C * $FILES$ * Library is vm * $SEEALSO$ * ACLONE(),ADEL(),AEVAL(),AFILL(),AINS(),ASORT() * $END$ */ /* $DOC$ * $TEMPLATE$ * Function * $NAME$ * ACLONE() * $CATEGORY$ * API * $SUBCATEGORY$ * Array * $ONELINER$ * Duplicate a multidimensional array * $SYNTAX$ * ACLONE() --> aDuplicate * $ARGUMENTS$ * Name of the array to be cloned. * $RETURNS$ * A new array pointer reference complete with nested * array values. * $DESCRIPTION$ * This function makes a complete copy of the array expressed as * and return a cloned set of array values. This provides * a complete set of arrays values for all dimensions within the * original array * $EXAMPLES$ * LOCAL aOne, aTwo * aOne := { "Harbour"," is ","POWER" } * aTwo := AClone( aOne ) // Result: aTwo is {"Harbour"," is ","POWER"} * aOne[ 1 ] := "The Harbour Compiler" * // Result: * // aOne is { "The Harbour Compiler", " is ", "POWER" } * // aTwo is { "Harbour"," is ","POWER" } * $STATUS$ * R * $COMPLIANCE$ * CA-Cl*pper will return NIL if the parameter is not an array. * $FILES$ * Library is vm * $SEEALSO$ * ACOPY(),ADEL(),AINS(),ASIZE() * $END$ */ /* $DOC$ * $TEMPLATE$ * Function * $NAME$ * ASORT() * $CATEGORY$ * API * $SUBCATEGORY$ * Array * $ONELINER$ * Sort an array * $SYNTAX$ * ASORT( , [], [], [] ) --> aArray * $ARGUMENTS$ * Array to be sorted. * * The first element to start the sort from, default is 1. * * Number of elements starting from to sort, default * is all elements. * * Code block for sorting order, default is ascending order * {| x, y | x < y }. The code block should accept two parameters and * must return .T. if the sort is in order, .F. if not. * $RETURNS$ * reference to the now sorted or NIL if the * passed is not an array. * $DESCRIPTION$ * ASORT() sort all or part of a given array. If is omitted, * the function expect to be one dimensional array containing * single data type (one of: Character, Date, Logical, Numeric) and sort * this array in ascending order: Character are sorted by their ASCII * value, Dates are sorted chronologically, Logical put .F. values before * .T., Numeric are sorted by their value. * * If is specified, it is used to handle the sorting order. With * each time the block is evaluate, two array elements are passed to the * code block, and must return a logical value that state if * those elements are in order (.T.) or not (.F.). Using this block you * can sort multidimensional array, descending orders or even (but why * would you want to do that) sort array that contain different data * type. * $EXAMPLES$ * // sort numeric values in ascending order * ASort( { 3, 1, 4, 42, 5, 9 } ) // result: { 1, 3, 4, 5, 9, 42 } * * // sort character strings in descending lexical order * aKeys := { "Ctrl", "Alt", "Delete" } * bSort := {| x, y | Upper( x ) > Upper( y ) } * ASort( aKeys,,, bSort ) // result: { "Delete", "Ctrl", "Alt" } * * // sort two-dimensional array according to 2nd element of each pair * aPair := { { "Sun", 8 }, { "Mon", 1 }, { "Tue", 57 }, { "Wed", -6 } } * ASort( aPair,,, {| x, y | x[ 2 ] < y[ 2 ] } ) * // result: { { "Wed", -6 }, { "Mon", 1 }, { "Sun", 8 }, { "Tue", 57 } } * $STATUS$ * R * $COMPLIANCE$ * C(arrayblock) * $FILES$ * Library is vm * $SEEALSO$ * ASCAN(),EVAL(),SORT * $END$ */