Sign in to follow this  
Followers 0
JohnOne

Trying to learn arrays

19 posts in this topic

#1 ·  Posted (edited)

Ive made an array and displayed it with _ArrayDisplay

Ive then used _ArrayTrim and displayed Trimed Array

But I was hoping to make that trimed array into a variable

At the moment arraydisplay is displaying $var

And MsgBox is displaying $avar

But Neither will display $avar1

The error is (C:\temp\readinitest.au3 (22) : ==> Subscript used with non-Array variable.: )

The script

#include <Array.au3>

Dim $avar[9] ; Declare array avar
Dim $avar1[9] ;Declare array avar1

$avar[0] = IniRead(@ScriptDir & "\new.initest.ini", "Section", "key1", "no data")
$avar[1] = IniRead(@ScriptDir & "\new.initest.ini", "Section", "key2", "no data")
$avar[2] = IniRead(@ScriptDir & "\new.initest.ini", "Section", "key3", "no data")
$avar[3] = IniRead(@ScriptDir & "\new.initest.ini", "Section", "key4", "no data")
$avar[4] = IniRead(@ScriptDir & "\new.initest.ini", "Section", "key5", "no data")
$avar[5] = IniRead(@ScriptDir & "\new.initest.ini", "Section", "key6", "no data")
$avar[6] = IniRead(@ScriptDir & "\new.initest.ini", "Section", "key7", "no data")
$avar[7] = IniRead(@ScriptDir & "\new.initest.ini", "Section", "key8", "no data")
$avar[8] = IniRead(@ScriptDir & "\new.initest.ini", "Section", "key9", "no data")

_ArrayDisplay($avar, "Before" )

$avar1 = _ArrayTrim($avar, 1, 1, 0, 8)
_ArrayDisplay($avar1, "After" )

MsgBox(0, "test $avar", $avar[0])
MsgBox(0, "test $avar1", $avar1[0])

Can someone explain where I'm going wrong please ?

Can an Array even be a variable ?

EDITED: line dim $avar1

Edited by JohnOne

AutoIt Absolute Beginners    Require a serial    Pause Script    Video Tutorials by Morthawt   ipify 

Monkey's are, like, natures humans.

Share this post


Link to post
Share on other sites



You have to flatten an array to display it in a message box.

$msg = ""

For $X = 0 to Ubound($avar)-1

$msg &= $avar[$X] & @CRLF

Next

MsgBox(0,'',$msg)

Share this post


Link to post
Share on other sites

JohnOne,

When you call _ArrayTrim it acts directly on the array it is trimming - that is what the ByRef means in the syntax line in the Help file:

#Include <Array.au3>
_ArrayTrim(ByRef $avArray, $iTrimNum[, $iDirection = 0[, $iStart = 0[, $iEnd = 0]]])

So you need to copy the array BEFORE you trim it if you want to have 2 arrays:

Dim $avar1[9] ; Declare array avar

$avar1[0] = IniRead(@ScriptDir & "\new.initest.ini", "Section", "key1", "no data")
$avar1[1] = IniRead(@ScriptDir & "\new.initest.ini", "Section", "key2", "no data")
$avar1[2] = IniRead(@ScriptDir & "\new.initest.ini", "Section", "key3", "no data")
$avar1[3] = IniRead(@ScriptDir & "\new.initest.ini", "Section", "key4", "no data")
$avar1[4] = IniRead(@ScriptDir & "\new.initest.ini", "Section", "key5", "no data")
$avar1[5] = IniRead(@ScriptDir & "\new.initest.ini", "Section", "key6", "no data")
$avar1[6] = IniRead(@ScriptDir & "\new.initest.ini", "Section", "key7", "no data")
$avar1[7] = IniRead(@ScriptDir & "\new.initest.ini", "Section", "key8", "no data")
$avar1[8] = IniRead(@ScriptDir & "\new.initest.ini", "Section", "key9", "no data")

$avar2 = $avar1 ; Copy array

_ArrayDisplay($avar1, "Before" )

_ArrayTrim($avar2, 1, 1);, 0, 8)

_ArrayDisplay($avar2, "After" )

Now you will get both "Before" and "After" _ArrayDisplays showing the correct values and 2 arrays - $avar1 = Before and $avar2 = After.

M23


Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind._______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

 

Share this post


Link to post
Share on other sites

JohnOne,

When you call _ArrayTrim it acts directly on the array it is trimming - that is what the ByRef means in the syntax line in the Help file:

I did see this in the help file but could not get my head around how to use it.

In the example given It was not used so I thought it was optional, and still havent used it in the script as yet.

For the record I have seen a few people on the forum refer to it, but even after reading the helpfile on ByRef, I still dont get it :D

It will come in the end

Thanks


AutoIt Absolute Beginners    Require a serial    Pause Script    Video Tutorials by Morthawt   ipify 

Monkey's are, like, natures humans.

Share this post


Link to post
Share on other sites

JohnOne,

When you pass parameters to a function you can do it in 2 ways:

By Value - This is the default. The parameter is treated as a Local variable and any changes made to it are lost when the function ends. So no changes are made to the variable within the function.

By Reference - This is used when ByRef is added BEFORE the variable name in the function parameter list. Now any changes to the variable made in the function also occur in the actual variable used a parameter.

Here is a small example:

$iVar1 = 10
$iVar2 = 20

funcA($iVar1, $iVar2)

ConsoleWrite($iVar1 & " - " & $iVar2 & @CRLF)

funcB($iVar1, $iVar2)

ConsoleWrite($iVar1 & " - " & $iVar2 & @CRLF)

Func funcA($iVar1, $iVar2)

    $iVar1 = 100
    $iVar2 = 200

EndFunc

Func funcB($iVar1, ByRef $iVar2)

    $iVar1 = 1000
    $iVar2 = 2000

EndFunc

As you can see, $iVar1 is never changed. $iVar2 is only changed when the ByRef keyword is used in the function syntax.

I hope this is clear. Ask if not.

M23


Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind._______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

 

Share this post


Link to post
Share on other sites

#11 ·  Posted (edited)

JohnOne,

When you pass parameters to a function you can do it in 2 ways:

By Value - This is the default. The parameter is treated as a Local variable and any changes made to it are lost when the function ends. So no changes are made to the variable within the function.

By Reference - This is used when ByRef is added BEFORE the variable name in the function parameter list. Now any changes to the variable made in the function also occur in the actual variable used a parameter.

Here is a small example:

$iVar1 = 10
$iVar2 = 20

funcA($iVar1, $iVar2)

ConsoleWrite($iVar1 & " - " & $iVar2 & @CRLF)

funcB($iVar1, $iVar2)

ConsoleWrite($iVar1 & " - " & $iVar2 & @CRLF)

Func funcA($iVar1, $iVar2)

    $iVar1 = 100
    $iVar2 = 200

EndFunc

Func funcB($iVar1, ByRef $iVar2)

    $iVar1 = 1000
    $iVar2 = 2000

EndFunc

As you can see, $iVar1 is never changed. $iVar2 is only changed when the ByRef keyword is used in the function syntax.

I hope this is clear. Ask if not.

M23

It does help.

But Im still a little confused

In my script here, the only data it gets from the ini file is "34" in all the elements of each array.

#include <Array.au3>
#include <file.au3>


; Declare Arrays

Dim $avar[9]
Dim $avar1[9]
Dim $avar2[9]
_FileWriteLog(@ScriptDir & "\my.log","Arrays Declared")


; Assign Values to elements in arrys

$avar[0] = IniRead(@ScriptDir & "\new.initest.ini", "Section", "key1", "no data")
$avar[1] = IniRead(@ScriptDir & "\new.initest.ini", "Section", "key2", "no data")
$avar[2] = IniRead(@ScriptDir & "\new.initest.ini", "Section", "key3", "no data")
$avar[3] = IniRead(@ScriptDir & "\new.initest.ini", "Section", "key4", "no data")
$avar[4] = IniRead(@ScriptDir & "\new.initest.ini", "Section", "key5", "no data")
$avar[5] = IniRead(@ScriptDir & "\new.initest.ini", "Section", "key6", "no data")
$avar[6] = IniRead(@ScriptDir & "\new.initest.ini", "Section", "key7", "no data")
$avar[7] = IniRead(@ScriptDir & "\new.initest.ini", "Section", "key8", "no data")
$avar[8] = IniRead(@ScriptDir & "\new.initest.ini", "Section", "key9", "no data")
_FileWriteLog(@ScriptDir & "\my.log","avar populated")

$avar1[0] = IniRead(@ScriptDir & "\new.initest.ini", "Section", "key1", "no data")
$avar1[1] = IniRead(@ScriptDir & "\new.initest.ini", "Section", "key2", "no data")
$avar1[2] = IniRead(@ScriptDir & "\new.initest.ini", "Section", "key3", "no data")
$avar1[3] = IniRead(@ScriptDir & "\new.initest.ini", "Section", "key4", "no data")
$avar1[4] = IniRead(@ScriptDir & "\new.initest.ini", "Section", "key5", "no data")
$avar1[5] = IniRead(@ScriptDir & "\new.initest.ini", "Section", "key6", "no data")
$avar1[6] = IniRead(@ScriptDir & "\new.initest.ini", "Section", "key7", "no data")
$avar1[7] = IniRead(@ScriptDir & "\new.initest.ini", "Section", "key8", "no data")
$avar1[8] = IniRead(@ScriptDir & "\new.initest.ini", "Section", "key9", "no data")
_FileWriteLog(@ScriptDir & "\my.log","avar1 populated")

$avar2[0] = IniRead(@ScriptDir & "\new.initest.ini", "Section", "key1", "no data")
$avar2[1] = IniRead(@ScriptDir & "\new.initest.ini", "Section", "key2", "no data")
$avar2[2] = IniRead(@ScriptDir & "\new.initest.ini", "Section", "key3", "no data")
$avar2[3] = IniRead(@ScriptDir & "\new.initest.ini", "Section", "key4", "no data")
$avar2[4] = IniRead(@ScriptDir & "\new.initest.ini", "Section", "key5", "no data")
$avar2[5] = IniRead(@ScriptDir & "\new.initest.ini", "Section", "key6", "no data")
$avar2[6] = IniRead(@ScriptDir & "\new.initest.ini", "Section", "key7", "no data")
$avar2[7] = IniRead(@ScriptDir & "\new.initest.ini", "Section", "key8", "no data")
$avar2[8] = IniRead(@ScriptDir & "\new.initest.ini", "Section", "key9", "no data")
_FileWriteLog(@ScriptDir & "\my.log","avar2 populated")


; Display and Trim array data

_ArrayDisplay($avar, "both")
_FileWriteLog(@ScriptDir & "\my.log","avar dislpayed")
_ArrayTrim($avar1, 1, 1, 0, 8)
_ArrayDisplay($avar1, "zero")
_FileWriteLog(@ScriptDir & "\my.log","avar1 displayed")
_ArrayTrim($avar2, 1, 0, 0, 8)
_ArrayDisplay($avar2, "one")
_FileWriteLog(@ScriptDir & "\my.log","avar2 displayed")

MsgBox(0, "test $avar", $avar[0])
MsgBox(0, "test $avar1", $avar1[0])
MsgBox(0, "test $avar2", $avar2[0])

The fist display gives "34" in all elements

The second display gives "3" in all elements

The third display gives "4" in all elements

The first msgbox gives "34"

The Second msgbox gives "3"

The Third msgbox gives"4"

So if I try to get any of the second and third display or msgbox outside this part of the script without using ByRef ,they will only give me "34" ?

Is that correct ?

I appreciate your time.

Edited by JohnOne

AutoIt Absolute Beginners    Require a serial    Pause Script    Video Tutorials by Morthawt   ipify 

Monkey's are, like, natures humans.

Share this post


Link to post
Share on other sites

JohnOne,

First point, you do not need to run through the .ini file 3 times. AutoIt has the ability to copy arrays - from the Help file:

A unique feature in AutoIt is the ability to copy arrays like this:

$mycopy = $myarray

In this case $mycopy will be an exact copy of $myarray and will have the same dimensions - no Dim statement is required to size the array first.

; ---- OK, to business:

ByRef ONLY works when passing parameters to a function. You cannot use ByRef in your script - that is what the Global and Local keywords are for (I guessed we might end up here! :D )

If you want variables to be used throughout your script, you need to declare them as Global. Then they will be available to every function within your script. By default, any variables you declare in the main body of your script (that is not between a Func and EndFunc) are Global - variables declared within functions are Local.

Why is this important? Well, Global variables can be modified within functions and do NOT have to be passed as parameters - in fact any variables passed as parameters are always regarded as Local unless ByRef is used.

Here is an expanded example to show what I mean:

Global $iVar1 = 10
Global $iVar2 = 20
Global $iVar3 = 30

funcA($iVar1, $iVar2)

ConsoleWrite($iVar1 & " - " & $iVar2 & " - " & $iVar3 & @CRLF)

funcB($iVar1, $iVar2)

ConsoleWrite($iVar1 & " - " & $iVar2 & " - " & $iVar3 & @CRLF)

Func funcA($iVar1, $iVar2)

    $iVar1 = 100
    $iVar2 = 200
    $iVar3 = 300

EndFunc

Func funcB($iVar1, ByRef $iVar2)

    $iVar1 = 1000
    $iVar2 = 2000
    $iVar3 = 3000

EndFunc

The result you should get is:

10 - 20 - 300
10 - 2000 - 3000

Let us explain why:

All 3 variables are declared Global, that means they are available to all functions in the script and do NOT have to be passed as parameters. If a function has a parameter with the same name, it is considered as a different variable and is classed automatically as Local. Any variable passed as a parameter with the ByRef keyword can be changed regardless of its Global/Local declaration. Let us run through the functions:

FuncA:

$iVar1 - declared Global, but passed as a parameter, so considered Local. Is not changed by the function.

$iVar2 - declared Global, but passed as a parameter, so considered Local. Is not changed by the function.

$iVar3 - declared Global, but NOT passed as a parameter, so considered Global. Is changed by the function.

FuncB:

$iVar1 - declared Global, but passed as a parameter, so considered Local. Is not changed by the function.

$iVar2 - declared Global, but passed as a parameter ByRef, so is changed by the function.

$iVar3 - declared Global, but NOT passed as a parameter, so considered Global. Is changed by the function.

Any questions? :D

M23


Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind._______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

 

Share this post


Link to post
Share on other sites

Thanks mate

Ive got it now :D

I've also learned what ConsoleWrite does (i've never looked at it)

And I new I'd seen that copy array thing before but was looking for ArrayCopy and CopyArray :D

No questions (I think)

I'm off to go and fart about with them for a day or so, to get familiar.

Thank you very glad once again for your guidance M23

Appreciated

John


AutoIt Absolute Beginners    Require a serial    Pause Script    Video Tutorials by Morthawt   ipify 

Monkey's are, like, natures humans.

Share this post


Link to post
Share on other sites

JohnOne,

Any time - glad I could help. :D

M23


Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind._______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

 

Share this post


Link to post
Share on other sites

#15 ·  Posted (edited)

I've been playing around and found a smashing little function in the help files that suits my purposes great.

"_StringExplode"

However I'm a little stuck on how to do something in the script

Here is the code and ini file I am working with

#include <String.au3>
#include <Array.au3>
#include <File.au3>


;Create Array from ini file

$text = IniRead(@ScriptDir & "\AutoIt-Test.ini", "Section", "thekey", "no data")
$array1 = _StringExplode($text, ",", 0)

$var1 = "Q"
$var2 = "W"

$hols = $var1 & $var2
If $hols = $array1[0] Or $hols = $array1[1] Or $hols = $array1[2] Or $hols = $array1[3] Or $hols = $array1[4] Or $hols = $array1[5] Or $hols = $array1[6] Or $hols = $array1[7] Or $hols = $array1[8] Then

    MsgBox(0, "Result", "Match " & $hols)

Else

    MsgBox(0, "Result", "No match Found")

EndIf

ini file

[Section]
thekey =AA,qw,qw,er,AA,88,er,qw,qw

I need to compare $hols against all of the elements in $array1

But at the moment I am having to enter them all individualy, but the data in the ini file could create a varying number of elements in the array

Is there a way to get around this?

Also, I would like to compare just the charactors in the elements, and not necessarily there order (if you get me), like in the code above Im looking for "QW", and would like a match if it were "WQ" stored in an element.

Ive been looking at _ArraySwap but it seems it swaps only one element for another.

If anyone can understand my ramblings I would really appreciate a nudge in the right direction.

Edited by JohnOne

AutoIt Absolute Beginners    Require a serial    Pause Script    Video Tutorials by Morthawt   ipify 

Monkey's are, like, natures humans.

Share this post


Link to post
Share on other sites

#16 ·  Posted (edited)

Ok I've figured out how to get result of string in any order using _StringReverse

;Files to include in script

#include <String.au3>
#include <Array.au3>
#include <File.au3>


;Create Array from ini file

$text = IniRead(@ScriptDir & "\AutoIt-Test.ini", "Section", "thekey", "no data")
$array1 = _StringExplode($text, ",", 0)

$var1 = "Q"
$var2 = "W"

$hols = $var1 & $var2

If $hols = $array1[0] Or $hols = $array1[1] Or $hols = $array1[2] Or $hols = $array1[3] Or $hols = $array1[4] Or $hols = $array1[5] Or $hols = $array1[6] Or $hols = $array1[7] Or $hols = $array1[8] Then

    MsgBox(0, "Result", "Match " & $hols)

Else

    $hols = _StringReverse($hols)

    If $hols = $array1[0] Or $hols = $array1[1] Or $hols = $array1[2] Or $hols = $array1[3] Or $hols = $array1[4] Or $hols = $array1[5] Or $hols = $array1[6] Or $hols = $array1[7] Or $hols = $array1[8] Then

        MsgBox(0, "Result", "Match " & $hols)

    Else

        MsgBox(0, "Result", "No match Found")

    EndIf


EndIf

Except I cant for the life of me figure how to check $hols against what may be a different amount of elements.

Edited by JohnOne

AutoIt Absolute Beginners    Require a serial    Pause Script    Video Tutorials by Morthawt   ipify 

Monkey's are, like, natures humans.

Share this post


Link to post
Share on other sites

JohnOne,

UBound is the total number of elements in an array. As AutoIt starts its arrays at element[0], the highest element is [UBound - 1].

As to shortening your If lines, try a bit of lateral thinking and reverse the order: :D

;Files to include in script

#include <String.au3>
#include <Array.au3>
#include <File.au3>


;Create Array from ini file
; Cannot be bothered to create an ini file
$text = "AA,qw,qw,er,AA,88,er,qw,qw" ;IniRead(@ScriptDir & "\AutoIt-Test.ini", "Section", "thekey", "no data")
$array1 = _StringExplode($text, ",", 0)

$var1 = "Q"
$var2 = "W"

$hols1 = $var1 & $var2
$hols2 = $var2 & $var1

For $i = 0 to UBound($array1) - 1  ; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< see how UBound is used?
    If $array1[$i] = $hols1 Or $array1[$i] = $hols2 Then
        MsgBox(0, "Result", "Match " & $array1[$i])
        Exit
    EndIf
Next

MsgBox(0, "Result", "No match Found")

Exit

Nice and short now! :D

M23


Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind._______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

 

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