Jump to content

Array walking


Phaser
 Share

Recommended Posts

Hi Guys

I have the following code, I want it to go to s specific point in the array and return 4 letters either side of that point in arraydisplay.

#include <GUIConstantsEx.au3>
#include <Array.au3>

Local $setstart,$setstartadjuster,$thestart
Local $1st[10]
Local $layoutarray[26] = ["A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z"]
HotKeySet("{ESC}", "killit")
Opt("GUIOnEventMode", 1)
GUICreate("Template", 260, 150)
GUISetOnEvent($GUI_EVENT_CLOSE, "killit")
$okbutton = GUICtrlCreateButton("Start", 50, 120, 60) ;ID 4
GUICtrlSetOnEvent($okbutton, "go")
$cancelbutton = GUICtrlCreateButton("Close", 150, 120, 60) ; ID 5
GUICtrlSetOnEvent($cancelbutton, "killit")
GUISetState()
loop()
Func go()
$theletter = "T"

$result2 = _ArraySearch($layoutarray,$theletter)
MsgBox(0,"window", "$result2 " & $result2)
$setstart = $result2+5; returns array key number setstart = 0
MsgBox(0,"window", "SetStart " & $setstart)

$i = 0
While $i < 5

    If $setstart+$i < 0 Then; catch setstart @ -1
        MsgBox(0,"window", "SetStartA " & $setstart)        
        $setstart = 25

        _ArrayPush($1st,$layoutarray[$setstart+$i],1)
        
    ElseIf $setstart+$i > 25 Then
        MsgBox(0,"window", "SetStartB " & $setstart)        
        $setstart = 0

        _ArrayPush($1st,$layoutarray[$setstart-$i],1)       
    
    Else
    
        _ArrayPush($1st,$layoutarray[$setstart+$i],1)
    
    EndIf   

    $i = $i +1

WEnd

_ArrayDisplay($1st)

EndFunc

Func killit()
    Exit
EndFunc

Func loop()

While 1
    
    Switch GUIGetMsg()
        Case $GUI_EVENT_CLOSE
            Exit
        Case $okbutton
            go()
            if BitAnd(GUICtrlRead($checkbox), $GUI_CHECKED) = True Then
            ExitLoop
            EndIf
    EndSwitch   
    
WEnd

EndFunc

The above starts at T moves 5 place up the array which is Y so the results I would like is

Backwards 4 UVWX Forwards 4 ZABC

Link to comment
Share on other sites

  • Moderators

Phaser,

Firstly, do not mix OnEvent and MessageLoop mode in the same script. As soon as you declare the Opt("GUIOnEventMode", 1), GUIGetMsg no longer functions as normal - just like it says in the Help file: ;)

"If the GUIOnEventMode option is set to 1 then the return from GUIGetMsg is always 0 and the @error is set to 1."

As to your little problem, I would do something like this:

#include <GUIConstantsEx.au3>
#include <Array.au3>

Local $setstart, $setstartadjuster, $thestart
Local $1st[10]
Local $layoutarray[26] = ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"]

HotKeySet("{ESC}", "killit")

Opt("GUIOnEventMode", 1)

GUICreate("Template", 260, 150)
GUISetOnEvent($GUI_EVENT_CLOSE, "killit")

$okbutton = GUICtrlCreateButton("Start", 50, 120, 60) ;ID 4
GUICtrlSetOnEvent($okbutton, "go")
$cancelbutton = GUICtrlCreateButton("Close", 150, 120, 60) ; ID 5
GUICtrlSetOnEvent($cancelbutton, "killit")

GUISetState()

While 1
    Sleep(10) ; All you need in OnEvent mode ;)
WEnd

Func go()

    $theletter = "T"

    ; Get the position in the array
    $result2 = _ArraySearch($layoutarray, $theletter)
    ConsoleWrite($result2 & @CRLF)

    ; Rather than go 5 forward and then 4 back - just go 4 forward :)
    For $i = 0 To 3 ; $result2 + 1 To $result2 + 5
        $j = $result2 + 1 + $i
        ; Convert the index if it is past the end of the array - you could also use Mod here ;)
        If $j > 25 Then $j -= 26
        $1st[$i] = $layoutarray[$j]
    Next
    ; Now jump an element and get the 4 past
    For $i = 4 To 7 ; $result2 + 6 To $result2 + 9
        $j = $result2 + 2 + $i
        If $j > 25 Then $j -= 26
        $1st[$i] = $layoutarray[$j]
    Next

    _ArrayDisplay($1st)

EndFunc   ;==>go

Func killit()
    Exit
EndFunc   ;==>killit

All clear? :)

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

Heres a simple example of what you want. I can see Melba's name in italics at the bottom though, so I'm guessing you have a solution :)

Essentially what you want to do is splice the array, but with it wrapping around.

#include<Array.au3>

Local $a[26] = ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"]


Local $i = 19 ; T
Local $aNew = _ArrayPlusMinus($a, $i)
_ArrayDisplay($aNew)

$i = 24 ; Y
$aNew = _ArrayPlusMinus($a, $i)
_ArrayDisplay($aNew)



Func _ArrayPlusMinus($aArray, $iItem, $iPlusMinus = 5)
    Local $aRet[$iPlusMinus * 2 + 1]

    Local $iStart = $iItem - $iPlusMinus

    Local $iSubScript
    For $i = 0 To $iPlusMinus * 2
        $iSubScript = $iStart + $i

        If $iSubScript < 0 Then $iSubScript += UBound($aArray)
        If $iSubScript > UBound($aArray) - 1 Then $iSubScript -= UBound($aArray)

        $aRet[$i] = $aArray[$iSubScript]
    Next

    Return $aRet
EndFunc   ;==>_ArrayPlusMinus
Edited by Mat
Link to comment
Share on other sites

Thanks Mat & Melba, I find Mats' a bit easier to adjust if I want to spread the catch further, say 6 each side, I just can't follow Melbas' code easily, I will fidle with both, I wish I could grasp it quicker, your code looks so neet compared to my poor attempts, can only learn from it I hope.

Thanks guys

Link to comment
Share on other sites

phaser,

This piece of code returns a string containing the plus/minus range of an array, skipping the target value (letter in this case).

Question for the experts:

"n - n - n" produces expected results, but, I vaguely recall reading a thread cautioning against this.

Any thoughts?

#include <Array.au3>

Local $arr10[26] = ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"]

local $rslt = range($arr10,_arraysearch($arr10,'B'))

consolewrite($rslt & @lf)

Func range($array,$target,$offset = 5)

    ;target < offset - wrap to end

    local $str

    if $target < $offset then
        for $j = $target - 1 to 0 step -1
            $str &= $array[$j]
        Next
        for $j = ubound($array) - 1 to ubound($array) - ($offset - $target) step -1
            $str &= $array[$j]
        Next
        for $j = $target + 1 to $offset + 1
            $str &= $array[$j]
        Next
        return $str
    EndIf

    ; offset > ubound($array) - target / wrap to beginning

    if $offset > ubound($array) - 1 - $target  then
        for $j = $target - $offset to $target - 1
            $str &= $array[$j]
        next
        for $j = ubound($array) - 1 - $target - 1 to 0 step - 1
            $str &= $array[ubound($array) - 1 - $j]
        Next
        for $j = 0 to $offset - (ubound($array) - 1 - $target) - 1
            $str &= $array[$j]
        next
        return $str
    endif

    ; offset does not wrap

    for $j = 0 - $offset to $offset
        if $array[$target - $j] = $target Then
            ContinueLoop
        Else
            $str &= $array[$target - $j]
        EndIf
    Next
    return $str
EndFunc

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

phaser,

Corrected logic error in no wrap routine.

#include <Array.au3>

Local $arr10[26] = ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"]

local $rslt = range($arr10,_arraysearch($arr10,'R'))

consolewrite($rslt & @lf)

Func range($array,$target,$offset = 5)

    ;target < offset - wrap to end

    local $str

    if $target < $offset then
        for $j = $target - 1 to 0 step -1
            $str &= $array[$j]
        Next
        for $j = ubound($array) - 1 to ubound($array) - ($offset - $target) step -1
            $str &= $array[$j]
        Next
        for $j = $target + 1 to $offset + 1
            $str &= $array[$j]
        Next
        return $str
    EndIf

    ; offset > ubound($array) - target / wrap to beginning

    if $offset > ubound($array) - 1 - $target  then
        for $j = $target - $offset to $target - 1
            $str &= $array[$j]
        next
        for $j = ubound($array) - 1 - $target - 1 to 0 step - 1
            $str &= $array[ubound($array) - 1 - $j]
        Next
        for $j = 0 to $offset - (ubound($array) - 1 - $target) - 1
            $str &= $array[$j]
        next
        return $str
    endif

    ; offset does not wrap

    for $j = $offset to 0 - $offset step - 1
        if $j = 0  Then
            ContinueLoop
        Else
            $str &= $array[$target - $j]
        EndIf
    Next
    return $str
EndFunc

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