Page 1 of 1
Extract column from array
Posted: Mon Jul 18, 2022 10:12 am
by Jack@007
Hi,
I'm a little bit rusty in VO.
My question concerns a multi dimensional array like:
a:={}
AAdd(a, {'a1', 'b1', 'c1'})
AAdd(a, {'a2', 'b2', 'c2'})
AAdd(a, {'a3', 'b3', 'c3'})
Extracting a row from the array is easy.
b:={}
b:=a[2]
(b equal "a2", "b2", "c2" ).
What would be the most efficiënt way to extract a column from an array (so the "b1", "b2", "b3" values)?
I'm not getting further than a for next loop.
TIA
Jack
Extract column from array
Posted: Mon Jul 18, 2022 11:57 am
by wriedmann
Hi Jack,
this could be done in a similar way:
Code: Select all
b:={}
for nI := 1 upto ALen( a )
AAdd( b, a[nI,2] )
next
Please not that this is not optimal code, it should only give you an idea.
If you need optimized code for this, please let me know.
Wolfgang
Extract column from array
Posted: Mon Jul 18, 2022 1:33 pm
by leon-ts
Hi Jack,
The following examples are not optimized, but visually simple:
Example 1
Code: Select all
LOCAL b := {} AS ARRAY // initialized array
AEval(a, {|x| AAdd(b, x[2])})
Example 2
Code: Select all
LOCAL b AS ARRAY // NULL_ARRAY
b := AEvalA(AClone(a), {|x| x[2]})
Best regards,
Leonid
Extract column from array
Posted: Mon Jul 18, 2022 1:54 pm
by Jack@007
Hi Wolfgang,
That approach is what i'm using now too.
Extract column from array
Posted: Mon Jul 18, 2022 1:55 pm
by Jack@007
Hi Leonid,
That's more the way i was looking for; a one liner to fill the new array.
Thanks.
Extract column from array
Posted: Mon Jul 18, 2022 1:59 pm
by wriedmann
Hi Jack,
if your arrays are small, the one liner works very well.
But if your arrays are larger, the one liners are using more memory.
Wolfgang
Extract column from array
Posted: Mon Jul 18, 2022 2:10 pm
by Jack@007
Hi Wolfgang,
The array i'm using has typical dimensions of 30x7 elements. I guess memory should be no problem. Correct me i i'm wrong.
Extract column from array
Posted: Mon Jul 18, 2022 2:21 pm
by wriedmann
Hi Jack,
with such small arrays that should not be a problem.
If the arrays become larger, creating the target array with the correct size helps a lot.
That would result in code like this:
Code: Select all
local nLen as dword
nLen := ALen( a )
b := ArrayNew( nLen )
for nI := 1 upto nLen
b[nI] := a[nI,2]
next
Wolfgang
Extract column from array
Posted: Mon Jul 18, 2022 2:30 pm
by leon-ts
Guys,
I think the best option is to write a function. It will be optimal both in terms of speed and memory, and will also be readable when used in code (one line).
The fastest and most optimized variant of the function (as far as I know VO):
Code: Select all
FUNCTION ACol(aSource AS ARRAY, dwElement AS DWORD) AS ARRAY PASCAL
LOCAL i, dwLen AS DWORD
LOCAL aResult, aI AS ARRAY
IF ( dwLen := ALen(aSource) ) > 0
aResult := ArrayCreate(dwLen)
FOR i := 1 UPTO dwLen
aI := ArrayGet(aSource, i)
ArrayPut(aResult, i, ArrayGet(aI, dwElement))
NEXT
ELSE
aResult := {}
ENDIF
RETURN aResult
Applying the ACol function in code:
Best regards,
Leonid