Page 1 of 2
AScan() a Multi-Dimensional Array
Posted: Thu Nov 24, 2022 2:37 am
by Red2
I need to AScan() a multi-dimensional array. It should be easy but I need your kind guidance.
// With a numeric 3-D array as follows:
LOCAL laPrimeCounts := { {10,1,0.1}, {100,25,0.2}, {1000,168,0.3}, {10000,1229,0.4}, {100000,9592,0.5}, ;
{1000000,78498,0.6}, {10000000,664579,0.7}, {100000000,5761455,0.8} }
// Example: My lines below return 0 (rather than the row #2):
lnColumn1_Hit := AScan( laPrimeCounts, 100 ) // Returns 0
lnColumn2_Hit := AScan( laPrimeCounts, 25 ) // Returns 0
lnColumn3_Hit := AScan( laPrimeCounts, 0.2 ) // Returns 0
QUESTION:
How can I AScan() an N-Dimension array (2-D, 3-D, or 4-D ) to identify the array row containing a value in a particular column?
I assume such a solution adapts for a character array, correct?
Thank you for your genereous help!
Red2
Re: AScan() a Multi-Dimensional Array
Posted: Thu Nov 24, 2022 8:07 am
by serge_girard
Red2,
Personnaly I would NOT use ASCAN...
I prefer my own little routine:
Code: Select all
FUNCTION MAIN()
/******************/
LOCAL laPrimeCounts := { ;
{10,1,0.1}, ;
{100,25,0.2}, ;
{1000,168,0.3}, ;
{10000,1229,0.4}, ;
{100000,9592,0.5}, ;
{1000000,78498,0.6}, ;
{10000000,664579,0.7}, ;
{100000000,5761455,0.8} }
SET PRINTER TO C:\test\SCAN.TXT
SET PRINTER ON
SET CONSOLE OFF
aSEARCH := {}
AADD(aSEARCH, 10000) // FOUND
AADD(aSEARCH, 664579) // FOUND
AADD(aSEARCH, 62364579) // NOT FOUND
AADD(aSEARCH, .03) // NOT FOUND
AADD(aSEARCH, .300) // FOUND
FOR xx := 1 to len(aSEARCH)
nSEARCH := aSEARCH [XX]
FOR a := 1 to len(laPrimeCounts)
FOR b := 1 to len(laPrimeCounts [a] )
IF laPrimeCounts [a,b ] == nSEARCH
? 'found', laPrimeCounts [a,b ]
ENDIF
NEXT
NEXT
NEXT
QUIT
This works very fine and easy to expand!
Serge
Re: AScan() a Multi-Dimensional Array
Posted: Thu Nov 24, 2022 2:08 pm
by Red2
Thank you very much Serge.
I can manually write code to iterate through an array's specific column.
I guess that what I really want to know is does the HMG syntax,
ASCAN( <aTarget>, <xSearch>, [<nStart>], [<nCount>] ) --> nStoppedAt
only support a 1-Dimensional array?
As of Visual FoxPro's version 7 one could specify the column to be scanned:
nResult = ASCAN( ArrayName, uExpression [, nStart [, nNumElems [, nColumn [, nFlags ] ] ] ] )
QUESTION:
Was column searching of a Multi-Dimensional array ever implemented in HMG or Harbour in a function?
If so I would appreciate it if the function and it's syntax would be shared.
Thanks again for all of your expert HMG guidance.
Red2
Re: AScan() a Multi-Dimensional Array
Posted: Thu Nov 24, 2022 2:18 pm
by serge_girard
Re: AScan() a Multi-Dimensional Array
Posted: Thu Nov 24, 2022 5:41 pm
by Red2
Thank you very much Serge for your help! I have looked at both of the URLs.
Only
https://harbour.github.io/doc/harbour.html#ascan
has a
Multi-Dimensional example.
I am confused. When running
either the
1) the web page's interactive example or
when running the example code
2) locally on my machine the result returned (by both) is
0.
Code: Select all
#include "directry.ch"
LOCAL nStoppedAt
LOCAL aDir := hb_vfDirectory( "*.prg" )
//
nStoppedAt := AScan( aDir,,, {| aFile, nPos | HB_SYMBOL_UNUSED( nPos ), aFile[ F_NAME ] == "Main.prg" } )
msginfo( "Result: " + NtoC( nStoppedAt ) // Returns 0
What mistakes am I making? Is something else going on?
I still have not been able to successfully run AScan() on my array locally:
Code: Select all
LOCAL laPrimeCounts := { {10,1}, {100,25}, {1000,168}, {10000,1229}, {100000,9592} ;
, {1000000,78498}, {10000000,664579}, {100000000,5761455} }
lnHit := AScan( laPrimeCounts, 100, 1 ) // Returns 0
Perhaps I do not understand AScan's syntax:
nStoppedAt := AScan( <aArray>, <xSearch>, [<nStart>], [<nCount>] )
aArray: Array to be scanned.
xSearch: Expression to search for in aTarget
nStart: Beginning subscript position at which to start the search.
nCount: Number of elements to scan with aTarget.
Does nStart refer to, the column number or row number?
Thanks again. Any suggestion that help me understand would be greatly appreciated.
Red2
Re: AScan() a Multi-Dimensional Array
Posted: Thu Nov 24, 2022 11:11 pm
by serge_girard
To be honest: I don't use ASCAN... I use my own FOR-NEXT loops! I always had a problem with ASCAN. Maybe somebody else knows right syntax/use.
Serge
Re: AScan() a Multi-Dimensional Array
Posted: Fri Nov 25, 2022 4:33 am
by AUGE_OHR
hi Red
search Filename in DIRECTORY Array
Code: Select all
aDir := DIRECTORY( cPath + "*.*", "DHS" )
nPosi := ASCAN( aDir, { | x | lower(x[ F_NAME ]) = lower(cFile) } )
sort DIRECTORY Array to have "D" on Top
Code: Select all
// "D"irectry on Top
ASORT( aDir,,, { | x, y | "D" $ x[ F_ATTR ] } )
AEVAL( aDir, { | x, i | nStartAt := IF( "D" $ x[ F_ATTR ], i, nStartAt ) } )
ASORT( aDir, 1, nStartAt, { | x, y | LOWER( x[ F_NAME ] ) < LOWER( y[ F_NAME ] ) } )
//now sort Size
IF ::SortOrder = LVS_SORTASCENDING
ASORT( aDirOut, nStartAt + 1,, { | x, y | ( x[ F_SIZE ] ) < ( y[ F_SIZE ] ) } )
ELSE
ASORT( aDirOut, nStartAt + 1,, { | x, y | ( x[ F_SIZE ] ) > ( y[ F_SIZE ] ) } )
ENDIF
Red2 wrote: ↑Thu Nov 24, 2022 5:41 pm
Does nStart refer to, the column number or row number?
on ROW
Re: AScan() a Multi-Dimensional Array
Posted: Fri Nov 25, 2022 7:16 am
by anupamgaurav22
Hi Red
you can try below code -
Code: Select all
LOCAL laPrimeCounts := { {10,1,0.1} ,;
{100,25,0.2},;
{1000,168,0.3},;
{10000,1229,0.4},;
{100000,9592,0.5},;
{1000000,78498,0.6},;
{10000000,664579,0.7},;
{100000000,5761455,0.8} }
? AScan( laPrimeCounts, { |arr| arr[1]==100 } )
? AScan( laPrimeCounts, { |arr| arr[2]==25 } )
? AScan( laPrimeCounts, { |arr| arr[3]==0.5 } )
Anupam
Re: AScan() a Multi-Dimensional Array
Posted: Fri Nov 25, 2022 7:54 am
by serge_girard
anupamgaurav22 solution is OK but.....
Code: Select all
LOCAL laPrimeCounts := { {10,1,0.1} ,;
{100,25,0.2},;
{1000,168,0.3},;
{10000,1229,0.4},;
{100000,9592,0.5},;
{100000,1119592,0.5},;
{100000,9522222292,0.5},;
{1000000,78498,0.6},;
{10000000,664579,0.7},;
{100000000,5761455,0.8} }
? AScan( laPrimeCounts, { |arr| arr[1]==100 } )
? AScan( laPrimeCounts, { |arr| arr[2]==25 } )
? AScan( laPrimeCounts, { |arr| arr[3]==0.5 } )
It will only find FIRST appearance of 0.5 in this array. My LOOP construction will find every appearance.
Or is there some flag missing saying all appearances?
S
Re: AScan() a Multi-Dimensional Array
Posted: Fri Nov 25, 2022 5:24 pm
by Red2
Hello all,
Serge's solution can identify a value in more than 1 array row. Thanks!
Jimmy's showed me interesting ways to manipulate arrays. Thanks!
Thank you anupamgaurav22! You taught me the AScan() syntax I needed for Multi-Dimensional array lookups.
This is exactly what I wanted. (Coming from a VFP background, code blocks are something I am slowly learning).
For what it is worth, this all came about from viewing the following video.
It challenged me to create,
using the HMG language, the fastest Prime Number generator program I could.
"E00: Software Drag Racing: C++ vs C# vs Python - Which Will Win?"
https://www.youtube.com/watch?v=D3h62rgewZM&t=717s
There are two considerations, the most efficient
algorithm and the
best use of a programming language.
I may not have accomplished either but it has been a great learning experience.
Interestingly using the same .PRG my results showed
Official HMG was 1.29% faster than
HMG Extended.
In case anyone is interested I plan on posting my "HMG" code in a day or two (after a little cleanup).
Thanks again for everyone's help!
Red2