PxPlus User Forum
Main Board => Discussions => Language => Topic started by: bteixeira on October 04, 2019, 09:12:51 AM
-
I'm trying to get the first element in an array that contains a substring. (Preferably without having to do a for loop)
DIM (FIND ) looked promising but it doesn't seem to work with the LIKE comparison.
Is there another way to do this?
-
The DIM FIND only accepts the standard =, <>, <, >, <=, or >= comparisons.
-
So to the original question, is there a way to find the first element of an array that contains a substring without using a for loop?
-
Here is a way to avoid using a FOR although it does use a bit more memory
def fn_find(local _arrayname$, local TEXT$)
local all$=sep+rec(cpl("IOLIST "+_arrayname$+"[ALL]"))
return pos(sep=all$(1,pos(TEXT$=all$)),1,0)
end def
!
dim x$[1:3]
x$[1]="Cute kitten"
x$[2]="Playful Puppy"
x$[3]="Noisy Bird"
!
print fn_find("x$","Puppy")
The fn_find() function takes the name of the array (as a string -- not the actual array) and the text to find. It then stuffs all elements in the array into a temporary string and scans it.
-
Here is an abuse of the range assignment to find the first element of an array that matches the pattern$. But a loop would be more readable and more efficient I guess.
def fn_find(array${all}, pattern$)
local idx = 1
array${all} = tbl(ior(array${all} like pattern$, and(0, ++idx)), array${all}, err=*next)
if not(tcb(2)) return dim(read min(array$)) - 1
return idx
end def
!
dim arr$[*]
arr$[*] = "alpha"; arr$[*] = "beta"
arr$[*] = "gamma"; arr$[*] = "delta"
!
idx = fn_find(arr${all}, "^.am.a$")
if idx print msg(="Entry that matches ""%3"" at index %1: %2", str(idx), arr$[idx], pattern$)
-
Frank,
Actually your post gave me another idea. Create a dummy array of match values then return the index of the first match.
def fn_find(local _array${all}, local TEXT$)
local dim _match[dim(read min(_array$)):dim(read max(_array$))]
_match{all}=_array${all} like TEXT$
return dim(find _match{all}<>0,err=*next)
return -1
end def
!
dim x$[1:3]
x$[1]="Cute kitten"
x$[2]="Playful Puppy"
x$[3]="Noisy Bird"
!
print fn_find(x${all},"Puppy")
-
Frank,
You don't really need to track the index yourself simply use TCB(18) as in:
def fn_find(local _array${all},pattern$)
_array${all}=tbl(_array${all} like pattern$,_array${all},err=*next)
if tcb(2) \
then return dim(read min(_array$))+tcb(18) \
else return dim(read min(_array$))-1
end def
!
dim arr$[*]
arr$[*]="alpha";
arr$[*]="beta"
arr$[*]="gamma";
arr$[*]="delta"
!
idx=fn_find(arr${all},"^.am.a$")
if idx \
then print msg(="Entry that matches ""%3"" at index %1: %2",str(idx),arr$[idx],pattern$)