Functions and Directives

Function AScan() Foundation

Searches an array for a specified value.

Syntax
AScan( <aArray>, <bxSeekExpr>, [<nStart>], [<nCount>]) --> nElement
Parameters
<aArray>
<aArray> is the array to search.
<bxSeekExpr>
<bxSeekExpr> is either a code block containing the search expression or a value of any other data type which is searched for in the array. When <bxSeekExpr> is not a code block, the array <aArray> must be one dimensional.
<nStart>
<nStart> is a numeric value specifying the first element in the array <aArray> to search. The default value is 1.
<nCount>
<nCount> is a numeric value indicating the number of elements searched starting from <nStart>. If <nCount> is missing, the array is searched from <nStart> to the last element.
Return

The return value of AScan() is a positive integer designating the first element where the value of <bxSeekExpr> is found. When <bxSeekExpr> is a code block, AScan() returns the position of the first element where the code block returns the value .T. (true). If the search is unsuccessful, AScan() returns zero.

Description

The array function AScan() is used to search an array for a value. If <bxSeekExpr> is not a code block, the value of <bxSeekExpr> is compared with the value of each array element. The search begins with the element <nStart> and compares <nCount> array elements. As soon as a match is found, AScan() terminates the search, returning the position of this array element as a numeric value. AScan() uses the simple equals operator (=) for the comparison. Because of this, the search of character strings is dependent on the settings SET EXACT, SET LEXICAL and SET COLLATION.

The array can have multiple dimensions. AScan() searches a value in all dimensions of a multi-dimensional array. The return value, however, points always to an array element of the first dimension.

When <bxSeekExpr> is a code block, the search occurs only in the first array dimension. AScan() evaluates the code block passing it the contents of each array element. The code block must perform a comparison and return a logical value. As soon as the code block returns .T. (true), AScan() terminates and returns the position of this element. The code block is necessary when a complex search condition must be used.

Examples
Search an array for a value using AScan()
// The example shows a search for a value in a one 
// dimensional array, with and without using a code block. 

PROCEDURE Main 
   LOCAL aArray 

   aArray := {"LPT1","LPT2","COM1","COM2","COM3"} 

   ? AScan( aArray, "COM2" )                // result: 4 
   ? AScan( aArray, "com2" )                // result: 0 

   SET EXACT OFF 
   ? AScan( aArray, "COM"  )                // result: 3 

   SET EXACT ON 
   ? AScan( aArray, "COM"  )                // result: 0 

   aArray := { 12, "Xbase++", Date(), .T. } 

   ? AScan( aArray, {|x| Valtype(x)=="C"} ) // result: 2 
   ? AScan( aArray, {|x| Valtype(x)=="O"} ) // result: 0 
RETURN 
Simple search of a multi-dimensional array
// The example shows a simple routine that translates 
// strings to numeric IDs and vice versa using a 
// two-dimensional array. 

#define ID_APPLES     100 
#define ID_PEARS      200 
#define ID_ORANGES    300 

PROCEDURE Main 
   CLS 
   ? Translate( ID_APPLES )                 // result: Apples 
   ? Translate( "Oranges" )                 // result: 300 
RETURN 

FUNCTION Translate( xValue ) 
   STATIC saTable := { ; 
     { ID_APPLES , "Apples"  }, ; 
     { ID_PEARS  , "Pears"   }, ; 
     { ID_ORANGES, "Oranges" }  ; 
   } 

   LOCAL i := AScan( saTable, xValue ) 

   IF i == 0 
      RETURN NIL 
   ENDIF 
RETURN IIF( Valtype(xValue)=="C", saTable[i,1], saTable[i,2] ) 
Complex search of a multi-dimensional array

// In the example the Directory() array is searched for all file 
// names with the "DBF" and "NTX" file extensions. The 
// element positions found are saved in a second array. 

#include "Directry.ch" 

PROCEDURE Main 
   LOCAL aArray, nElement, nStart, nEnd, aFound 

   aArray := Directory("*.*") 
   aFound := {} 
   nStart := 1 
   nEnd   := Len( aArray ) 
   DO WHILE nStart <= nEnd 
      nElement := AScan( aArray, ;   // search from nStart 
                         {|a| ".DBF" $ Upper( a[F_NAME] ) .OR.; 
                              ".NTX" $ Upper( a[F_NAME] ) }, ; 
                         nStart ) 
      IF nElement == 0               // no match found 
         EXIT 
      ENDIF 

      AAdd( aFound, nElement )       // save position 
      nStart := nElement + 1         // new start position 
   ENDDO 
                                     // display file 
                                     // names found 
   AEval( aFound, {|n| QOut(aArray[n,F_NAME]) } ) 

RETURN 

Feedback

If you see anything in the documentation that is not correct, does not match your experience with the particular feature or requires further clarification, please use this form to report a documentation issue.