PxPlus User Forum

Twitter Twitter Twitter

Author Topic: DIM (FIND ) and LIKE  (Read 2239 times)

bteixeira

  • Silver Member
  • ***
  • Posts: 27
    • View Profile
DIM (FIND ) and LIKE
« 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?

Mike King

  • Diamond Member
  • *****
  • Posts: 3817
  • Mike King
    • View Profile
    • BBSysco Consulting
Re: DIM (FIND ) and LIKE
« Reply #1 on: October 04, 2019, 10:27:15 AM »
The DIM FIND only accepts the standard =, <>, <, >, <=, or >= comparisons.
Mike King
President - BBSysco Consulting
eMail: mike.king@bbsysco.com

bteixeira

  • Silver Member
  • ***
  • Posts: 27
    • View Profile
Re: DIM (FIND ) and LIKE
« Reply #2 on: October 04, 2019, 10:32:58 AM »
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?

Mike King

  • Diamond Member
  • *****
  • Posts: 3817
  • Mike King
    • View Profile
    • BBSysco Consulting
Re: DIM (FIND ) and LIKE
« Reply #3 on: October 04, 2019, 11:08:05 AM »
Here is a way to avoid using a FOR although it does use a bit more memory


Code: [Select]
  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.
Mike King
President - BBSysco Consulting
eMail: mike.king@bbsysco.com

Frank Dreßler

  • Guest
Re: DIM (FIND ) and LIKE
« Reply #4 on: October 04, 2019, 12:20:09 PM »
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.

Code: [Select]
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$)

Mike King

  • Diamond Member
  • *****
  • Posts: 3817
  • Mike King
    • View Profile
    • BBSysco Consulting
Re: DIM (FIND ) and LIKE
« Reply #5 on: October 04, 2019, 01:18:18 PM »
Frank,

Actually your post gave me another idea.  Create a dummy array of match values then return the index of the first match.

Code: [Select]
  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")
« Last Edit: October 04, 2019, 01:23:12 PM by Mike King »
Mike King
President - BBSysco Consulting
eMail: mike.king@bbsysco.com

Mike King

  • Diamond Member
  • *****
  • Posts: 3817
  • Mike King
    • View Profile
    • BBSysco Consulting
Re: DIM (FIND ) and LIKE
« Reply #6 on: October 04, 2019, 01:45:33 PM »
Frank,

You don't really need to track the index yourself simply use TCB(18) as in:

Code: [Select]
  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$)


Mike King
President - BBSysco Consulting
eMail: mike.king@bbsysco.com