Sign in to follow this  
Followers 0
archrival

A faster alternative to _ArraySearch?

8 posts in this topic

#1 ·  Posted (edited)

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

Share this post


Link to post
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...

1100111 00001011101111 00011101101111 00010111100100 00001111110100 00110111110010 00101101111001 0011100i didn't make up this form of encryption, but i like it.credit to the lvl 6 challenge on arcanum.co.nz

Share this post


Link to post
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...


1100111 00001011101111 00011101101111 00010111100100 00001111110100 00110111110010 00101101111001 0011100i didn't make up this form of encryption, but i like it.credit to the lvl 6 challenge on arcanum.co.nz

Share this post


Link to post
Share on other sites

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


[center]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.[/center]

Share this post


Link to post
Share on other sites

#5 ·  Posted (edited)

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

Visit the SciTE4AutoIt3 Download page for the latest versions        Beta files                                                          Forum Rules
 
Live for the present,
Dream of the future,
Learn from the past.
  :)

Share this post


Link to post
Share on other sites

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

[center]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.[/center]

Share this post


Link to post
Share on other sites

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

Visit the SciTE4AutoIt3 Download page for the latest versions        Beta files                                                          Forum Rules
 
Live for the present,
Dream of the future,
Learn from the past.
  :)

Share this post


Link to post
Share on other sites

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


[center]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.[/center]

Share this post


Link to post
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
Sign in to follow this  
Followers 0