Jump to content

_ArraySearch and _ArrayFindAll


Recommended Posts

_Arraysearch only seems to find the first instance of what I am searching for. Whereas _ArrayFindAll only returns the element numbers (but does find all of them)

is there a way to make _ArraySearch find more than 1 instance? Or make _ArrayFindAll return the actual values rather than the elements?

Link to comment
Share on other sites

options for both below:

Local $array[5]=[1,1,1,3,4]
$iStart = 0
While True
 $value = _ArraySearch($array, 1, $iStart)
 If $value>=0 Then
  ConsoleWrite("array subscript=[" & $value & "] Value=" & $array[$value] & @CRLF)
 Else
  ExitLoop
 EndIf
 $iStart = $value + 1
WEnd
Local $array[5]=[1,1,1,3,4]
$aSub = _ArrayFindAll($array, 1)
For $i = 0 To UBound($aSub)-1
 ConsoleWrite("array subscript=[" & $aSub[$i] & "] Value=" & $array[$aSub[$i]] & @CRLF)
Next
IEbyXPATH-Grab IE DOM objects by XPATH IEscriptRecord-Makings of an IE script recorder ExcelFromXML-Create Excel docs without excel installed GetAllWindowControls-Output all control data on a given window.
Link to comment
Share on other sites

The _ArrayFindAll option looks easier

#include <Array.au3>

Local $avArray[5] = [10, 11, 12, 11, 10]
Local $aiResult = _ArrayFindAll($avArray, "10")
_ArrayDisplay($avArray, "$avArray")

Dim $aiResult2[UBound($aiResult)][2]
For $i = 0 to UBound($aiResult)-1
  $aiResult2[$i][0] = $aiResult[$i]
  $aiResult2[$i][1] = $avArray[$aiResult[$i]]
Next
_ArrayDisplay($aiResult2, "Results of searching for 10 in $avArray")

Edited by mikell
Link to comment
Share on other sites

mikell,

_arrayfindall runs _arraysearch in a loop. Since you going to have to process the results anyway why not cut out the middle man, like this...

#include <array.au3>

local $my_array[10] = ['a',0,'what','0',1,2,'2','1','what',1]

; example # 1 find all ocurrences of 2 and return as string
ConsoleWrite(__arrayfindall($my_array,'2') & @LF)

; example # 2 find all ocurrences of 'what' and return as array
local $aTmp = __arrayfindall($my_array,'what',0)
_arraydisplay($aTmp)


func __arrayfindall(byref $array,$srch,$ret_type = 1)

    ;  usage
    ;    $array    - array to search
    ;    $srch     - string to search for
    ;    $ret_type - 0 = return array, 1 = return a '|' delimited string

    local $tmp

    for $1 = 0 to ubound($array) - 1
        if $array[$1] == $srch Then $tmp &= $array[$1] & '|'
    next

    $tmp = stringtrimright($tmp,1)

    if $ret_type = 0 then
        return stringsplit($tmp,'|')
    Else
        return $tmp
    EndIf

endfunc

kylomas

edit:spelling

Edited by kylomas

Forum Rules         Procedure for posting code

"I like pigs.  Dogs look up to us.  Cats look down on us.  Pigs treat us as equals."

- Sir Winston Churchill

Link to comment
Share on other sites

mikell,

What you are asking for does not seem terribly usefull so I expanded it a bit. The function will return one of the following:

1 - 2D array [0] = element #

[1] = value at element #

2 - string formated as element#-value|element#-value...

The function also supports "fuzzy" searching (parameter). If the search argument is contained anywhere in the element it will match.

Give it a whirl and see what you think...

#include <array.au3>

local $gennum = 50000, $aTestArray[$gennum], $StrLen = 5, $TestString

for $1 = 0 to $gennum - 1
    for $2 = 1 to $StrLen
        $aTestArray[$1] &= chr(random(65,90,1))
    Next
Next

local $st = timerinit()
local $aTmp = __arrayfindall($aTestArray,'Z',0,0)
ConsoleWrite(stringformat('!  Time to run %05i entries = %3.4f seconds for %4i matches',$gennum,timerdiff($st)/1000,ubound($aTmp)-1) & @LF)
_arraydisplay($aTmp)

func __arrayfindall(byref $array,$srch,$ret_type = 1,$fuzzy = 1)

    ;  usage
    ;    $array    - array to search
    ;    $srch     - string to search for
    ;    $ret_type - 0 = return 2D array of ele # and value
    ;                 1 = return a '|' delimited string of element#-value
    ;     $fuzzy    - 0 = find any ocurrence of string within the element
    ;               - 1 = element must strictly equal the string (default)

    local $tmp, $aTmp[ubound($array)][2],$ele = 0

    for $1 = 0 to ubound($array) - 1

        switch $fuzzy
            case 1
                if $array[$1] == $srch Then
                    $aTmp[$ele][0] = $1
                    $aTmp[$ele][1] = $array[$1]
                    $ele += 1
                endif
            case 0
                if stringregexp($array[$1],$srch) = 1 Then
                    $aTmp[$ele][0] = $1
                    $aTmp[$ele][1] = $array[$1]
                    $ele += 1
                endif
        endswitch

    next

    ; find # of hits

    local $row_cnt
    for $1 = 0 to ubound($aTmp) - 1
        if stringlen($aTmp[$1][0]) > 0  then ContinueLoop
        $row_cnt = $1
        ExitLoop
    next

    ; shrink array

    redim $aTmp[$row_cnt+1][2]

    if $ret_type = 0 then
        return $aTmp
    Else
        for $1 = 0 to ubound($aTmp) - 1
            $tmp &= $aTmp[$1][0] & '-' & $aTmp[$1][1] & '|'
        Next
        return stringtrimright($tmp,3)
    EndIf

endfunc

edit: - multiple changes

Edited by kylomas

Forum Rules         Procedure for posting code

"I like pigs.  Dogs look up to us.  Cats look down on us.  Pigs treat us as equals."

- Sir Winston Churchill

Link to comment
Share on other sites

And just for the sake of completeness...

This function will return either a 2D array as

[0] - matching element number

[1] - matching element value (seems redundant)

or a string formatted as element#-element value|element#-element value....

and you can specify the kind of match as

0 - match if element contains the search argument

1 - match if element is equal to the search argument

2 - match if element starts with the search argument

3 - match if element ends with the argument

The example code searches an array of 5000 random length elements (1-200 chars) of capital letters for any elements containing the string "ZOO". The general search time is appx. .03 seconds.

#include <array.au3>

local $gennum = 5000
local $aTestArray[$gennum], $StrLen = 10, $TestString

for $1 = 0 to $gennum - 1
    for $2 = 1 to random(1,100,1)
        $aTestArray[$1] &= chr(random(65,90,1))
    Next
Next

local $st = timerinit()
local $aTmp = __arrayfindall($aTestArray,'ZOO',0,0)
ConsoleWrite(stringformat('!  Time to run %05i entries = %3.4f seconds for %4i matches',$gennum,timerdiff($st)/1000,ubound($aTmp)-1) & @LF)
_arraydisplay($aTmp)

ConsoleWrite(__arrayfindall($aTestArray,'ZOO',1,0) & @LF)


func __arrayfindall(byref $array,$srch,$ret_type = 1,$srch_type = 1)

    ;  usage
    ;    $array    - array to search
    ;    $srch     - string to search for
    ;    $ret_type - 0 = return 2D array of ele # and value
    ;               - 1 = return a '|' delimited string of element#-value (default)
    ;     $srch_type- 0 = find any ocurrence of string within the element
    ;               - 1 = element equals the string (default)
    ;               - 2 = element starts with search string
    ;               - 3 = element ends with search string

    local $tmp, $aTmp[ubound($array)][2],$ele = 0

    for $1 = 0 to ubound($array) - 1

        switch $srch_type
            case 1
                if $array[$1] == $srch Then
                    $aTmp[$ele][0] = $1
                    $aTmp[$ele][1] = $array[$1]
                    $ele += 1
                endif
            case 0
                if stringregexp($array[$1],$srch) = 1 Then
                    $aTmp[$ele][0] = $1
                    $aTmp[$ele][1] = $array[$1]
                    $ele += 1
                endif
            case 2
                if stringregexp($array[$1],'^' & $srch) = 1 Then
                    $aTmp[$ele][0] = $1
                    $aTmp[$ele][1] = $array[$1]
                    $ele += 1
                endif
            case 3
                if stringregexp($array[$1],$srch & '$') = 1 Then
                    $aTmp[$ele][0] = $1
                    $aTmp[$ele][1] = $array[$1]
                    $ele += 1
                endif
        endswitch

    next

    ; find # of hits

    local $row_cnt
    for $1 = 0 to ubound($aTmp) - 1
        if stringlen($aTmp[$1][0]) > 0  then ContinueLoop
        $row_cnt = $1
        ExitLoop
    next

    ; shrink array

    redim $aTmp[$row_cnt+1][2]

    if $ret_type = 0 then
        return $aTmp
    Else
        for $1 = 0 to ubound($aTmp) - 1
            $tmp &= $aTmp[$1][0] & '-' & $aTmp[$1][1] & '|'
        Next
        return stringtrimright($tmp,3)
    EndIf

endfunc

kylomas

Edited by kylomas

Forum Rules         Procedure for posting code

"I like pigs.  Dogs look up to us.  Cats look down on us.  Pigs treat us as equals."

- Sir Winston Churchill

Link to comment
Share on other sites

kylomas

What wisem2540 was asking for did not seem very useful indeed, that's why I didn't go further than playing a bit with the example from the helpfile

Of course your func is quite more efficient and helpful, so even if I didn't ask for it I will still store this in my own array-dedicated library

Nice work, thanks :)

Link to comment
Share on other sites

mikell,

My mistake, apologies! I got this mental myopia thing going on...I hope you find it usefull.

kylomas

edit: A note of caution...I don't flush the parms nor do I verify that the string delimiter does not participate in the result string.

Edited by kylomas

Forum Rules         Procedure for posting code

"I like pigs.  Dogs look up to us.  Cats look down on us.  Pigs treat us as equals."

- Sir Winston Churchill

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...