ACopy()
This function copies data from one array to another. Sounds simple, doesn't it? But it's not because ACOPY() doesn't require a one-to-one correspondence between the two arrays. You can copy from any consecutive set of elements in the source array to consecutive positions anywhere in the destination array. You can even copy data from one place to another in the same array! As with many array functions, ACOPY() doesn't care if the arrays you hand it are one-dimensional or two-dimensional; it treats them as one-dimensional. You supply a starting element and number of elements to copy from the source array and a starting element in the destination array.
Usage |
nNumberCopied = ACOPY(SourceArray, DestArray [, nSourceStart [, nSourceLength [, nDestStart ] ] ] ) |
Parameter |
Value |
Meaning |
SourceArray |
Array Name |
The array containing the data to be copied. It can be one- or two-dimensional, but must exist. |
DestArray |
Array Name |
The array to which data is copied. If it doesn't exist, Visual FoxPro creates it and makes it identical in dimensions to SourceArray. If it's too small to hold the number of elements copied, as many elements as fit are copied and then an error is generated. If DestArray is larger than the number of items copied, extra array elements are left alone. If DestArray has a different shape, elements are simply copied in order and the array is not reshaped to match the source. |
nSourceStart |
Numeric |
The first element of SourceArray to be copied. This is always an element number, even if SourceArray is two-dimensional. |
Omitted |
All elements in SourceArray are copied. |
|
nSourceLength |
Numeric |
The number of elements copied. |
Omitted |
All elements from nSourceStart to the end of the array are copied. |
|
nDestStart |
Numeric |
The first element of DestArray where copied data is placed. Copying continues from that element toward the end of the array. |
Omitted |
Data is placed in DestArray beginning at the first element. |
|
nNumberCopied |
Numeric |
The number of items copied. |
Example |
DIMENSION aSample[3,2] * fill the array FOR nCnt = 1 TO 6 aSample[nCnt]=nCnt ENDFOR * copy the whole array = ACOPY(aSample, aNew) DISPLAY MEMORY LIKE A* && shows new array && identical to the original * copy the last row = ACOPY(aSample, aOneRow, 5) DISPLAY MEMORY LIKE A* && shows new array && with one row filled in * copy the second row = ACOPY(aSample, aSecond, 3, 2) DISPLAY MEMORY LIKE A* && shows new array && again one row filled in * create a large, one-dimensional array DIMENSION aLarge[50] * copy the entire first array positioning at item 11 = ACOPY(aSample, aLarge, 1, 6, 11) DISPLAY MEMORY LIKE A* && show result * now copy last 3 elements positioning at item 25 = ACOPY(aSample, aLarge, 4, 3, 25) DISPLAY MEMORY && show result |
The examples show one really weird behavior of ACOPY(). When the destination array doesn't exist, FoxPro creates it and makes it match the source array. Sounds sensible, except for one thing. It does it even when copying only a subset of the element in the source. Take a look again at what happens when you copy only one row of the source to aOneRow—the new array is still 3x2 even though only the first row contains data. This behavior is documented, but we can't see why it was designed this way. |
FUNCTION aColCopy * Copy one or more columns from a source array to a destination array. LPARAMETERS aSource, aDest, nStartCol, nColCount, nDestCol * aSource = array to be copied * aDest = destination array * nStartCol = first column to copy - required * nColCount = number of columns to copy - optional. * Go to end of aSource, if omitted * nDestCol = first column of destination to receive copied data - optional * 1 if omitted LOCAL nRetVal,nOldRows,nOldCols,nOldCount,nItem * nRetVal = return value, number of columns copied. * = -1, if can't copy * Check source array IF TYPE("aSource[1]")="U" OR ALEN(aSource,2)=0 * not a 2-d array, can't do it RETURN -1 ENDIF * Check for starting column IF TYPE("nStartCol")<>"N" RETURN -1 ENDIF * Check number of columns. Compute if necessary IF TYPE("nColCount")<>"N" OR nStartCol+nColCount>ALEN(aSource,2) nColCount=ALEN(aSource,2)-nStartCol+1 ENDIF * Check destination column. IF TYPE("nDestCol")<>"N" nDestCol=1 ENDIF * Check destination array for size. It must exist to be passed in. * First, make sure it's an array. * Then, see if it's shaped right for all the data. * Two cases - if enough cols, but not enough rows, can just add * If not enough cols, have to move data around. IF TYPE("aDest[1]")="U" DIMENSION aDest[ALEN(aSource,1),nColCount+nDestCol-1] ELSE IF ALEN(aDest,2)>=nColCount+nDestCol-1 && enough columns IF ALEN(aDest,1)<ALEN(aSource,1) && not enough rows DIMENSION aDest[ALEN(aSource,1),ALEN(aDest,2)] && add some ENDIF ELSE * now the hard one * not enough columns, so need to add more (and maybe rows, too) nOldRows=ALEN(aDest,1) nOldCols=ALEN(aDest,2) nOldCount=ALEN(aDest) DIMENSION aDest[MAX(nOldRows,ALEN(aSource,1)),nColCount+nDestCol-1] * DIMENSION doesn't preserve data location, so we need to adjust the data * We go backward from the end of the array toward the front, moving data * down, so we don't overwrite any data by accident FOR nItem=nOldCount TO 2 STEP -1 * Use new item number and old dimensions to determine * new item number for each element IF nOldCols<>0 nRow=CEILING(nItem/nOldCols) nCol=MOD(nItem,nOldCols) IF nCol=0 nCol=1 ENDIF ELSE nRow=nItem nCol=1 ENDIF aDest[nRow,nCol]=aDest[nItem] ENDFOR ENDIF ENDIF * finally ready to start copying FOR nCol=1 TO nColCount FOR nRow=1 TO ALEN(aSource,1) aDest[nRow,nDestCol+nCol-1]=aSource[nRow,nStartCol+nCol-1] ENDFOR ENDFOR RETURN nColCount*ALEN(aSource,1)For example, suppose you want just the filenames from an ADIR() listing. You could use aColCopy() like this:
=ADIR(aFiles) DIMENSION aNames[1] =aColCopy(@aFiles,@aNames,1,1)
See Also |
ADel(), AElement(), AIns(), Array Manipulation, ASubscript(), Copy To Array, Dimension |