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()
*-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._
