Jump to content

ArraySearch Problem


Recommended Posts

I have a problem that just started since AutoIt v3.3.11.4 was released.

My script is modifying an xml file created in another program. It searches for the end of the <resources> section and adds some additional file references. However, this is now failing in v3.3.11.4 beta.

Consider this code:

$idx = _ArraySearch($xmlArr, "</resource>" 0, 0, 0, 1, 0)

This code used to work in v3.3.11.3 and returned the last index of the $xmlArr where the search string was found. Now this fails with @error 6 which means the string was not found, while _ArrayDisplay() indicates the value IS located in the array.

Since the file has some white space (tabs, etc) before the string, I think it may be failing because I'm not using a regular expression. However, the spec for the function indicates a stingInStr search is supposed to be performed.

Has anyone else found this to be a problem?

I changed to using _ArrayFindAll() and the script works again.
 

Link to comment
Share on other sites

  • Moderators

CliftonL,

Can you please post an example of the array (or better the XML file and the code to convert it) and I will take look. It might take a while - I am currently using my phone on a cross-Channel ferry so I cannot run any code until I reach my destination later today.

M23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Link to comment
Share on other sites

  • Moderators

CliftonL,

I found the bug - the UDF was setting the search bounds after having reversed the limits when searching backwards. Swapping the order fixes it:

#include <Array.au3>

Global $aArray[5] = ["blah", "<resource>", "blah", "</resource>", "blah"]

_ArrayDisplay($aArray, "", Default, 8)

$iIndex = _ArraySearch_Mod($aArray, "</resource>", 0,     0,   0,    1,       1)
;                                                  start, end, case, compare, forward
MsgBox($MB_SYSTEMMODAL, "Found forward", "Index: " & $iIndex)

$iIndex = _ArraySearch_Mod($aArray, "</resource>", 0,     0,   0,    1,       0)
;                                                  start, end, case, compare, backward
MsgBox($MB_SYSTEMMODAL, "Found backward", "Index: " & $iIndex)

Func _ArraySearch_Mod(Const ByRef $avArray, $vValue, $iStart = 0, $iEnd = 0, $iCase = 0, $iCompare = 0, $iForward = 1, $iSubItem = -1, $bRow = False)

    If $iStart = Default Then $iStart = 0
    If $iEnd = Default Then $iEnd = 0
    If $iCase = Default Then $iCase = 0
    If $iCompare = Default Then $iCompare = 0
    If $iForward = Default Then $iForward = 1
    If $iSubItem = Default Then $iSubItem = -1
    If $bRow = Default Then $bRow = False

    If Not IsArray($avArray) Then Return SetError(1, 0, -1)
    Local $iDim_1 = UBound($avArray) - 1
    If $iDim_1 = -1 Then Return SetError(3, 0, -1)
    Local $iDim_2 = UBound($avArray, $UBOUND_COLUMNS) - 1

    ; Same var Type of comparison
    Local $bCompType = False
    If $iCompare = 2 Then
        $iCompare = 0
        $bCompType = True
    EndIf
    ; Bounds checking
    If $bRow Then
        If UBound($avArray, $UBOUND_DIMENSIONS) = 1 Then Return SetError(5, 0, -1)
        If $iEnd < 1 Or $iEnd > $iDim_2 Then $iEnd = $iDim_2
        If $iStart < 0 Then $iStart = 0
        If $iStart > $iEnd Then Return SetError(4, 0, -1)
    Else
        If $iEnd < 1 Or $iEnd > $iDim_1 Then $iEnd = $iDim_1
        If $iStart < 0 Then $iStart = 0
        If $iStart > $iEnd Then Return SetError(4, 0, -1)
    EndIf
    ; Direction (flip if $iForward = 0)
    Local $iStep = 1
    If Not $iForward Then
        Local $iTmp = $iStart
        $iStart = $iEnd
        $iEnd = $iTmp
        $iStep = -1
    EndIf

    Switch UBound($avArray, $UBOUND_DIMENSIONS)
        Case 1 ; 1D array search
            If Not $iCompare Then
                If Not $iCase Then
                    For $i = $iStart To $iEnd Step $iStep
                        If $bCompType And VarGetType($avArray[$i]) <> VarGetType($vValue) Then ContinueLoop
                        If $avArray[$i] = $vValue Then Return $i
                    Next
                Else
                    For $i = $iStart To $iEnd Step $iStep
                        If $bCompType And VarGetType($avArray[$i]) <> VarGetType($vValue) Then ContinueLoop
                        If $avArray[$i] == $vValue Then Return $i
                    Next
                EndIf
            Else
                For $i = $iStart To $iEnd Step $iStep
                    If $iCompare = 3 Then
                        If StringRegExp($avArray[$i], $vValue) Then Return $i
                    Else
                        If StringInStr($avArray[$i], $vValue, $iCase) > 0 Then Return $i
                    EndIf
                Next
            EndIf
        Case 2 ; 2D array search
            Local $iDim_Sub
            If $bRow Then
                ; Search rows
                $iDim_Sub = $iDim_1
                If $iSubItem > $iDim_Sub Then $iSubItem = $iDim_Sub
                If $iSubItem < 0 Then
                    ; will search for all Col
                    $iSubItem = 0
                Else
                    $iDim_Sub = $iSubItem
                EndIf
            Else
                ; Search columns
                $iDim_Sub = $iDim_2
                If $iSubItem > $iDim_Sub Then $iSubItem = $iDim_Sub
                If $iSubItem < 0 Then
                    ; will search for all Col
                    $iSubItem = 0
                Else
                    $iDim_Sub = $iSubItem
                EndIf
            EndIf
            ; Now do the search
            For $j = $iSubItem To $iDim_Sub
                If Not $iCompare Then
                    If Not $iCase Then
                        For $i = $iStart To $iEnd Step $iStep
                            If $bRow Then
                                If $bCompType And VarGetType($avArray[$j][$j]) <> VarGetType($vValue) Then ContinueLoop
                                If $avArray[$j][$i] = $vValue Then Return $i
                            Else
                                If $bCompType And VarGetType($avArray[$i][$j]) <> VarGetType($vValue) Then ContinueLoop
                                If $avArray[$i][$j] = $vValue Then Return $i
                            EndIf
                        Next
                    Else
                        For $i = $iStart To $iEnd Step $iStep
                            If $bRow Then
                                If $bCompType And VarGetType($avArray[$j][$i]) <> VarGetType($vValue) Then ContinueLoop
                                If $avArray[$j][$i] == $vValue Then Return $i
                            Else
                                If $bCompType And VarGetType($avArray[$i][$j]) <> VarGetType($vValue) Then ContinueLoop
                                If $avArray[$i][$j] == $vValue Then Return $i
                            EndIf
                        Next
                    EndIf
                Else
                    For $i = $iStart To $iEnd Step $iStep
                        If $iCompare = 3 Then
                            If $bRow Then
                                If StringRegExp($avArray[$j][$i], $vValue) Then Return $i
                            Else
                                If StringRegExp($avArray[$i][$j], $vValue) Then Return $i
                            EndIf
                        Else
                            If $bRow Then
                                If StringInStr($avArray[$j][$i], $vValue, $iCase) > 0 Then Return $i
                            Else
                                If StringInStr($avArray[$i][$j], $vValue, $iCase) > 0 Then Return $i
                            EndIf
                        EndIf
                    Next
                EndIf
            Next
        Case Else
            Return SetError(2, 0, -1)
    EndSwitch
    Return SetError(6, 0, -1)
EndFunc   ;==>_ArraySearch_Mod
Thanks for pointing it out - as soon as I get back to an SVN-capable machine I will commit the change. :)

M23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

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