Jump to content

A faster alternative to _ArraySearch?


 Share

Recommended Posts

Is there a faster way to perform this function? The array is created very quickly without any verification of a previous instance of $player_id. The speed takes a serious hit when I add the _ArraySearch function. Basically this just creates and array of about 1200 6 digit numbers, some could possibly be in the array already and I want to make sure that each number is only listed once. This function is in another For/Next loop.

For $i = 1 to 50
    $idloc = StringInStr($text, "playerID=", 0, $i)
    If $idloc > 0 Then
        $player_id = StringMid($text, $idloc + 9, 6)
        If Not IsArray($id_array) Then
            $id_array = _ArrayCreate ($player_id)
        Else
            $key = _ArraySearch ($id_array, $player_id)
            Select
                Case $key = -1
                _ArrayAdd($id_array, $player_id)
            EndSelect
        EndIf
    EndIf
Next
Edited by archrival
Link to comment
Share on other sites

Is there a faster way to perform this function? The array is created very quickly without any verification of a previous instance of $player_id. The speed takes a serious hit when I add the _ArraySearch function. Basically this just creates and array of about 1200 6 digit numbers, some could possibly be in the array already and I want to make sure that each number is only listed once. This function is in another For/Next loop.

For $i = 1 to 50
    $idloc = StringInStr($text, "playerID=", 0, $i)
    If $idloc > 0 Then
        $player_id = StringMid($text, $idloc + 9, 6)
        If Not IsArray($id_array) Then
            $id_array = _ArrayCreate ($player_id)
        Else
            $key = _ArraySearch ($id_array, $player_id)
            Select
                Case $key = -1
                _ArrayAdd($id_array, $player_id)
            EndSelect
        EndIf
    EndIf
Next
rather than searching each time before the add, i'd say to just add it, then sort the array and remove the dupes... so you're only really searching through it once...
Link to comment
Share on other sites

rather than searching each time before the add, i'd say to just add it, then sort the array and remove the dupes... so you're only really searching through it once...

i didn't see an _arrayremovedupes() in the array.au3, so i just made one real quick. it does it's own sort, then removes dupes. so you don't have to pass it an ordered array or anything:

#include<array.au3>
#cs
    Title:              _ArrayRemoveDupes
    Version:            v1.0
    FileName:           ArrayRemoveDupes.au3
    Description:        Removes duplicate elements from given array.
    Author(s)           CameronsDad - Sean - AIM: SiCKPrLck
#ce
Func _ArrayRemoveDupes($InArray)
    Dim $TempArray[$InArray[0]+1][2]
    $TempArray[0][0] = $InArray[0]
    For $x = 1 to $InArray[0]
        $TempArray[$x][0] = $InArray[$x]
        $TempArray[$x][1] = $x
    Next
Dim $inner,$outer,$temp,$temp2
$n = $temparray[0][0]
$h = 1
While $h <= $n/3
    $h = $h * 3 + 1
WEnd

While $h >0
    For $outer = $h To $n
        $temp = $temparray[$outer][0]
        $temp2 = Number(StringStripWS($temparray[$outer][1],1))
        $inner = $outer
        While $inner > ($h - 1) And StringLower($temparray[$inner-$h][0]) >= StringLower($temp)
            $temparray[$inner][0] = $temparray[$inner-$h][0]
            $temparray[$inner][1] = $temparray[$inner-$h][1]
            $inner = $inner - $h
        WEnd
        $temparray[$inner][0] = $temp
        $temparray[$inner][1] = $temp2
    Next
$h = ($h - 1)/3
WEnd    
For $blah = 1 To $temparray[0][0]-1
    If $TempArray[$blah][0] = $temparray[$blah + 1][0] Then 
        _ArrayDelete($InArray,$temparray[$blah][1])
        $InArray[0] = $InArray[0]-1
    EndIf
Next
Return($InArray)
EndFunc

sorry if one of these already existed, i didn't search the forums, just did it because i had nothing better to do...

Link to comment
Share on other sites

  • Moderators

Hmmm, I helped them by doing:

Local $MakeAList
$Value = 'Whatever it is through this loop'
If StringInString($MakeAList, $Value) = 0 Then
    $MakeAList = $MakeAList & $Value & @LF
EndIf

But at least there's a UDF for it now!! :P

Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.

Link to comment
Share on other sites

  • Developers

Hmmm, I helped them by doing:

Local $MakeAList
$Value = 'Whatever it is through this loop'
If StringInString($MakeAList, $Value) = 0 Then
    $MakeAList = $MakeAList & $Value & @LF
EndIf

But at least there's a UDF for it now!! :lmao:

When developing Tidy I found out tat searching a string with delimiters is a lot faster than using Arrays, only your code has a logic problem when the Key you search is a substring of another key: e.g Key1=Hallo and Key2 = all.

This logic doesn't have that issue:

Global $MakeAList = @LF
ConsoleWrite('1. CheckUnique("AAA") = ' & CheckUnique("AAA") & @lf)
ConsoleWrite('2. CheckUnique("AAA") = ' & CheckUnique("AAA") & @lf)
ConsoleWrite('3. CheckUnique("AA") = ' & CheckUnique("AA") & @lf)
ConsoleWrite('4. CheckUnique("AA") = ' & CheckUnique("AA") & @lf)

Func CheckUnique($Value)
    If StringInStr($MakeAList, @LF & $Value & @LF) Then Return 0
    $MakeAList = $MakeAList & $Value & @LF
    Return 1
EndFunc;==>CheckUnique

Oh and StringInString() should be StringInStr() :P

Edited by JdeB

SciTE4AutoIt3 Full installer Download page   - Beta files       Read before posting     How to post scriptsource   Forum etiquette  Forum Rules 
 
Live for the present,
Dream of the future,
Learn from the past.
  :)

Link to comment
Share on other sites

  • Moderators

Ha... Nice one Jdeb, I didn't even look, I hate typing in the window!! :P

Actually though... I started thinking after I wrote that (I use it the above UDF all the time in my own scripts) the Pros and Cons of either, and found that mine does have a logice flaw!... If the string your making 'unique' has an @LF macro in it your not going to get the proper result... Do you have a suggestion maybe around that?

This is the code I use:

Func _ArrayNoDupes(ByRef $nArray)
    Local $MakeAList
    For $i = 1 To UBound($nArray) - 1
        If StringInStr(@LF & $MakeAList, @LF & $nArray[$i] & @LF) = 0 Then $MakeAList = $MakeAList & $nArray[$i] & @LF
    Next
    Return StringSplit(StringTrimRight($MakeAList, 1), @LF)
EndFunc

Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.

Link to comment
Share on other sites

  • Developers

Do you have a suggestion maybe around that?

You have to choose a delimiter but can also use chr(01) as the delimiter which will work in most cases ...

SciTE4AutoIt3 Full installer Download page   - Beta files       Read before posting     How to post scriptsource   Forum etiquette  Forum Rules 
 
Live for the present,
Dream of the future,
Learn from the past.
  :)

Link to comment
Share on other sites

  • Moderators

You have to choose a delimiter but can also use chr(01) as the delimiter which will work in most cases ...

Great Idea Jdeb, I think I will change my UDF to Chr(01) rather than @LF :P

Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.

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...