Tag Archives: LEN()
String Functions
CharAdd
CharAnd
CharEven
CharHist
CharList
CharMirr
CharMix
CharNoList
CharNot
CharOdd
CharOne
CharOnly
CharOr
CharPix
CharRela
CharRelRep
CharRem
CharRepl
CharRLL
CharRLR
CharSHL
CharSHR
CharSList
CharSort
CharSub
CharSwap
CharWin
CharXOR
CountLeft
CountRight
Descend
Empty
hb_At
hb_RAt
hb_ValToStr
IsAlpha
IsDigit
IsLower
IsUpper
NumAt
NumToken
PadLeft
PadRight
POSALPHA
POSCHAR
POSDEL
POSDIFF
POSEQUAL
POSINS
POSLOWER
POSRANGE
POSREPL
POSUPPER
TokenAt
TokenEnd
TokenExit
TokenInit
TokenLower
TokenNext
TokenNum
TokenSep
TokenUpper
Empty()
EMPTY()
Checks if the passed argument is empty.
Syntax
EMPTY( <xExp> ) --> lIsEmpty
Arguments
<xExp> is any valid expression.
Returns
A logical value. It is true (.T.) if the passed argument is empty otherwise it is false (.F.).
Description
This function checks if an expression has empty value and returns a logical indicating whether it the expression is empty or not.
Note : Characters with ASCII code 9, 10 and 13 always treated as “white spaces”;
Examples
? EMPTY( "I'm not empty" ) // .F.
Tests
PROCEDURE Test() ? EMPTY( NIL ) // .T. ? EMPTY( 0 ) // .T. ? EMPTY( .F. ) // .T. ? EMPTY( "" ) // .T. ? EMPTY( 1 ) // .F. ? EMPTY( .T. ) // .F. ? EMPTY( "smile" ) // .F. ? EMPTY( Date() ) // .F. ? EMPTY( {} ) // .T. ? EMPTY( {''} ) // .F. ? EMPTY( {=>} ) ) // .T. ? EMPTY( CHR(8) ) // .F. ? EMPTY( CHR(9) ) // .T. ? EMPTY( CHR(10) ) // .T. RETURN
Compliance
Clipper
Files
Library is rtl
Seealso
LEN()
FieldName()
FIELDNAME()
Return the name of a field at a numeric field location.
Syntax
FIELDNAME/FIELD(<nPosition>) --> cFieldName
Arguments
<nPosition> Field order in the database.
Returns
<cFieldName> returns the field name.
Description
This function return the name of the field at the <nPosition>th position. If the numeric value passed to this function does not correspond to an existing field in the designated or selected work area, this function will return a NULL byte.
Examples
PROCEDURE Main() LOCAL x USE tests NEW FOR x := 1 TO tests->( FCOUNT() ) ? "Field Name", FieldName( x ) NEXT USE RETURN
Compliance
Clipper
Files
Library is rdd
Seealso
DBSTRUCT(), FCOUNT(), LEN(), VALTYPE()
ATail()
ATAIL()
Returns the rightmost element of an array
Syntax
ATAIL( <aArray> ) --> Element
Arguments
<aArray> is the array.
Returns
<Element> the expression of the last element in the array.
Description
This function return the value of the last element in the array named <aArray>. 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"
Compliance
Clipper
Files
Library is vm
Seealso
LEN(), ARRAY(), ASIZE(), AADD()
SP_AMATCHES
AMATCHES() Short: ------ AMATCHES() Counts the matches of an array with condition Returns: -------- <nMatches> => Number of matches Syntax: ------- AMATCHES(aTarget,[bCondition]) Description: ------------ <aTarget> is the target array. Normally an array of numeric values. [bCondition] is an optional codeblock used to select a subset of the array. This could be used to filter out 0's or non-numeric elements. The block must accept an array element as a parameter, and return true or false <expL> to determine if this element is part of the desired subset. Without [bCondition], the length of the array is returned. Examples: --------- v := AMATCHES(aSales) v := AMATCHES(aSales,{|e|valtype(e)=="N".and.e<>0}) v := AMATCHES(aSales,{|e|valtype(e)=="C".and.e=="D"}) Source: ------- S_ASTATS.PRG
SP_ALENG
ALENG() Short: ------ ALENG() Actual length of an array, less trailing nil elements Returns: -------- <aLength> => Actual array length, less trailing NILs Syntax: ------- ALENG(aTarget) Description: ------------ Determines the actual length of <aTarget>, less trailing nils. Examples: --------- a := {1,2,3,4,5,nil,nil,nil} ?len(a) // => returns 8 ?aleng(a) // => returns 5 Notes: ------ This was a C function in prior Super.Libs Source: ------- S_ALENG.PRG
SP_AFLENSX
AFLENSX() Short: ------ AFLENSX() Returns an array of field LENGTHS for current dbf Returns: -------- <aFields> => an array of field LENGTHS for the current dbf Syntax: ------- AFLENSX() Description: ------------ AFLENSX() creates and returns an array of field lengths from the current dbf. Unlike AFIELDS(), it does not require an initialized array beforehand. Examples: --------- aArray := AFIELDSX() aTypes := AFTYPESX() aLens := AFLENSX() aDeci := AFDECIX() if (nSelect := mchoice(aArray,10,10,20,20,"Pick Field")) > 0 ?"Field "+aArray[nSelect]+" was selected" ?" of type "+aTypes[nSelect] ?" of length "+aLens[nSelect] ?" of decimals "+aDeci[nSelect] endif Source: ------- S_AFTYPE.PRG
C5_LEN
LEN() Return the length of a character string or the number of elements in an array ------------------------------------------------------------------------------ Syntax LEN(<cString> | <aTarget>) --> nCount Arguments <cString> is the character string to count. <aTarget> is the array to count. Returns LEN() returns the length of a character string or the number of elements in an array as an integer numeric value. If the character string is a null string ("") or the array is empty, LEN() returns zero. Description LEN() is a character and array function that returns the length of a character string or the number of elements in an array. With a character string, each byte counts as one, including an embedded null byte (CHR(0)). By contrast, a null string ("") counts as zero. For an array, LEN() returns the number of elements. If the array is multidimensional, subarrays count as one element. This means that the LEN() of a nested or multidimensional array simply returns the length of the first dimension. To determine the number of elements in other dimensions, use LEN() on the subarrays as shown in the example below. Note that nested arrays in Clipper need not have uniform dimensions. Examples . These examples demonstrate LEN() with various arguments: ? LEN("string of characters") // Result: 20 ? LEN("") // Result: 0 ? LEN(CHR(0)) // Result: 1 // LOCAL aTest[10] ? LEN(aTest) // Result: 10 . This example creates a literal two-dimensional array, and then returns the number of elements in the subarray contained in the first element of the original array: LOCAL aArray := { {1, 2}, {1, 2}, {1, 2} } ? LEN(aArray) // Result: 3 ? LEN(aArray[1]) // Result: 2 . This example navigates a multidimensional array using LEN(): LOCAL aArray := { {1, 2}, {1, 2}, {1, 2} } LOCAL nRow, nColumn, nRowCount, nColumnCount // nRowCount = LEN(aArray) FOR nRow = 1 TO nRowCount nColumnCount = LEN(aArray[nRow]) FOR nColumn = 1 TO nColumnCount ? nRow, nColumn, aArray[nRow][nColumn] NEXT NEXT . In this example a function returns an array of numeric values that describe the dimensions of a nested or multidimensional array. The function assumes that the array has uniform dimensions: FUNCTION Dimensions( aArray ) LOCAL aDims := {} DO WHILE ( VALTYPE(aArray) == "A" ) AADD( aDims, LEN(aArray) ) aArray := aArray[1] ENDDO RETURN (aDims) Files Library is CLIPPER.LIB.
See Also: AADD() ASIZE() LTRIM() RTRIM()
Hash vs Table
Consider a table for customers records with two character fields : Customer ID and customer name:
Cust_ID | Cust_Name |
CC001 | Pierce Firth |
CC002 | Stellan Taylor |
CC003 | Chris Cherry |
CC004 | Amanda Baranski |
It’s known all possible and necessary operations on a table: APPEND, DELETE, SEEK and so on; by the way, for SEEK we need an index file also.
Listing this table is quite simple:
USE CUSTOMER
WHILE .NOT. EOF()
? CUST_ID, CUST_NAME
DBSKIP()
ENDDO
If our table is sufficiently small, we can find a customer record without index and SEEK :
LOCATE FOR CUST_ID = “CC003”
? CUST_ID, CUST_NAME
If we want all our data will stand in memory and we could manage it more simple and quick way, we would use an array ( with some considerations about size of table; if it is too big, this method will be problematic ) :
aCustomer := {} // Declare / define an empty array
USE CUSTOMER
WHILE .NOT. EOF()
AADD(aCustomer, { CUST_ID, CUST_NAME } )
DBSKIP()
ENDDO
Traversing this array is quite simple :
FOR nRecord := 1 TO LEN( aCustomer )
? aCustomer[ nRecord, 1 ], aCustomer[ nRecord, 2 ]
NEXT
or :
a1Record := {}
FOR EACH a1Record IN aCustomer
? a1Record[ 1 ], a1Record[ 2 ]
NEXT
And locating a specific record too:
nRecord := ASCAN( aCustomer, { | a1Record | a1Record[ 1 ] == “CC003” } )
? aCustomer[ nRecord, 1 ], aCustomer[ nRecord, 2 ]
A lot of array functions are ready to use for maintain this array : ADEL(), AADD(), AINS() etc …
Now, let’s see how we could use a hash for achieve this job :
hCustomer := { => } // Declare / define an empty hash
USE CUSTOMER
WHILE .NOT. EOF()
hCustomer[ CUST_ID ] := CUST_NAME
DBSKIP()
ENDDO
Let’s traversing :
h1Record := NIL
FOR EACH h1Record IN hCustomer
? h1Record: __ENUMKEY(),h1Record:__ENUMVALUE()
NEXT
Now, we have a bit complicate our job; a few field addition to the table :
No: | Field Name | Type | Width | Dec | Decription |
1 |
CUST_ID |
C |
5 |
0 |
Id ( Code ) |
2 |
CUST_NAME |
C |
10 |
0 |
Name |
3 |
CUST_SNAM |
C |
10 |
0 |
Surname |
4 |
CUST_FDAT |
D |
8 |
0 |
First date |
5 |
CUST_ACTV |
L |
1 |
0 |
Is active ? |
6 |
CUST_BLNCE |
N |
11 |
2 |
Balance |
While <key> part of an element of a hash may be C / D / N / L type; <xValue> part of hash too may be ANY type of data, exactly same as arrays.
So, we can make fields values other than first ( ID) elements of an array:
hCustomer := { => } // Declare / define an empty hash
USE CUSTOMER
WHILE .NOT. EOF()
a1Data:= { CUST_NAME, CUST_SNAM, CUST_FDAT, CUST_ACTV, CUST_BLNCE }
hCustomer[ CUST_ID ] := a1Data
DBSKIP()
ENDDO
Let’s traversing :
h1Record := NIL
FOR EACH h1Record IN hCustomer
a1Key := h1Record:__ENUMKEY()
a1Data := h1Record:__ENUMVALUE()
? a1Key
AEVAL( a1Data, { | x1 | QQOUT( x1 ) } )
NEXT *-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._ /* Hash vs Tables */ #define NTrim( n ) LTRIM( STR( n ) ) #define cLMarj SPACE( 3 ) PROCEDURE Main() SET DATE GERM SET CENT ON SET COLO TO "W/B" SetMode( 40, 120 ) CLS hCustomers := { => } // Declare / define an empty PRIVATE hash IF MakUseTable() Table2Hash() * Here the hash hCustomers may be altered in any way ZAP Hash2Table() ELSE ? "Couldn't make / USE table" ENDIF ? @ MAXROW(), 0 WAIT "EOF HashVsTable.prg" RETURN // HashVsTable.Main() *-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._. PROCEDURE Table2Hash() hCustomers := { => } WHILE .NOT. EOF() hCustomers[ CUST_ID ] := CUST_SNAM DBSKIP() ENDDO ListHash( hCustomers, "A hash transferred from a table (single value)" ) hCustomers := { => } // Declare / define an empty hash DBGOTOP() WHILE .NOT. EOF() hCustomers[ CUST_ID ] := { CUST_NAME, CUST_SNAM, CUST_FDAT, CUST_ACTV, CUST_BLNCE } DBSKIP() ENDDO ListHash( hCustomers, "A hash transferred from a table (multiple values)" ) RETURN // Table2Hash() *-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._. PROCEDURE Hash2Table() LOCAL h1Record,; c1Key,; a1Record,; n1Field FOR EACH h1Record IN hCustomers c1Key := h1Record:__ENUMKEY() a1Record := h1Record:__ENUMVALUE() DBAPPEND() FIELDPUT( 1, c1Key ) AEVAL( a1Record, { | x1, n1 | FIELDPUT( n1 + 1 , x1 ) } ) NEXT h1Record DBGOTOP() ? ? "Data trasferred from hash to table :" ? WHILE ! EOF() ? STR( RECN(), 5), '' FOR n1Field := 1 TO FCOUNT() ?? FIELDGET( n1Field ), '' NEXT n1Field DBSKIP() ENDDO RETURN // Hash2Table() *-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._. PROCEDURE ListHash( hHash, cComment ) LOCAL x1Pair cComment := IF( HB_ISNIL( cComment ), '', cComment ) ? ? cComment // , "-- Type :", VALTYPE( hHash ), "size:", LEN( hHash ) ? IF HB_ISHASH( hHash ) FOR EACH x1Pair IN hHash nIndex := x1Pair:__ENUMINDEX() x1Key := x1Pair:__ENUMKEY() x1Value := x1Pair:__ENUMVALUE() ? cLMarj, NTrim( nIndex ) * ?? '', VALTYPE( x1Pair ) ?? '', x1Key, "=>" * ?? '', VALTYPE( x1Key ) * ?? VALTYPE( x1Value ) IF HB_ISARRAY( x1Value ) AEVAL( x1Value, { | x1 | QQOUT( '', x1 ) } ) ELSE ?? '', x1Value ENDIF NEXT ELSE ? "Data type error; Expected hash, came", VALTYPE( hHash ) ENDIF HB_ISHASH( hHash )
RETURN // ListHash() *-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._. FUNCTION MakUseTable() // Make / USE table LOCAL cTablName := "CUSTOMER.DBF" LOCAL lRetval, aStru, aData, a1Record IF FILE( cTablName ) USE (cTablName) ELSE aStru := { { "CUST_ID", "C", 5, 0 },; { "CUST_NAME", "C", 10, 0 },; { "CUST_SNAM", "C", 10, 0 },; { "CUST_FDAT", "D", 8, 0 },; { "CUST_ACTV", "L", 1, 0 },; { "CUST_BLNCE", "N", 11, 2 } } * * 5-th parameter of DBCREATE() is alias - * if not given then WA is open without alias * ^^^^^^^^^^^^^ DBCREATE( cTablName, aStru, , .F., "CUSTOMER" ) aData := { { "CC001", "Pierce", "Firth", 0d20120131, .T., 150.00 },; { "CC002", "Stellan", "Taylor", 0d20050505, .T., 0.15 },; { "CC003", "Chris", "Cherry", 0d19950302, .F., 0 },; { "CC004", "Amanda", "Baranski", 0d20011112, .T., 12345.00 } } FOR EACH a1Record IN aData CUSTOMER->(DBAPPEND()) AEVAL( a1Record, { | x1, nI1 | FIELDPUT( nI1, X1 ) } ) NEXT a1Record DBGOTOP() ENDIF lRetval := ( ALIAS() == "CUSTOMER" ) RETURN lRetval // MakUseTable() *-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._