gcue

flexibility with declaring an array

28 posts in this topic

#1 ·  Posted (edited)

hello world!
 
i have a really large array i keep modifying .. wondering if there was a way to declare it in such a way that was easy to modify.. somtimes i need to delete records from the middle which throws the count off.. if something like this was possible it would make it much easier... then again - not sure what the first line Local $array[10] would look like since i wouldnt know the final count yet
 
thanks in advance!
 
#include <array.au3>

Local $array[10]


$x = 0


$array[$x += 1] = "bob"
$array[$x += 1] = "larry"
$array[$x += 1] = "mark"
$array[$x += 1] = "will"
$array[$x += 1] = "pete"
$array[$x += 1] = "martha"
$array[$x += 1] = "jane"
$array[$x += 1] = "jill"
$array[$x += 1] = "jack"
$array[$x += 1] = "jim"

_ArrayDisplay($array)
Edited by gcue

Share this post


Link to post
Share on other sites



this would work (not sure if its the best way).. but the first line i guess would have to be figured out manually - cant think of another way around that

#include <array.au3>


Local $array[10]


$x = 0


$array[$x] = "bob"
$x +=1
$array[$x] = "larry"
$x +=1
$array[$x] = "mark"
$x +=1
$array[$x] = "will"
$x +=1
$array[$x] = "pete"
$x +=1
$array[$x] = "martha"
$x +=1
$array[$x] = "jane"
$x +=1
$array[$x] = "jill"
$x +=1
$array[$x] = "jack"
$x +=1
$array[$x] = "jim"


_ArrayDisplay($array)

Share this post


Link to post
Share on other sites

#3 ·  Posted (edited)

Although I haven't actually tried them, I believe Maps in beta would probably be ideal for this. There are various ways to handle this with arrays. One way is to use a 2D array with an ID (identifier) column which you can search. Another way, which I demonstrate below, is to track changes using a second array.

;

#include <Array.au3>

Local $aArray[10]
Local Enum $eBob = 1, $eLarry, $eMark, $eWill, $ePete, $eMartha, $eJane, $eJill, $eJack

$aArray[0] = "Deleted"
$aArray[$eBob] = "bob"
$aArray[$eLarry] = "larry"
$aArray[$eMark] = "mark"
$aArray[$eWill] = "will"
$aArray[$ePete] = "pete"
$aArray[$eMartha] = "martha"
$aArray[$eJane] = "jane"
$aArray[$eJill] = "jill"
$aArray[$eJack] = "jack"
_ArrayDisplay($aArray)

Local $aID[UBound($aArray)] ; Second array to track changes in $aArray

For $i = 1 To UBound($aID) -1
    $aID[$i] = $i ; Each element points to a value in $aArray
Next
;_ArrayDisplay($aID)

; Delete "pete"
$aID[$ePete] = 0
For $i = $ePete +1 To UBound($aID) -1
    $aID[$i] -= 1
Next
_ArrayDelete($aArray, $ePete)
_ArrayDisplay($aArray)

; Access "jane"
MsgBox(0, "Access jane", $aArray[$aID[$eJane]])

; Access "pete"
MsgBox(0, "Access pete", $aArray[$aID[$ePete]])

;

This is not a general solution and you will have to work out how to also add items if you use this approach, and write the functions you need.

Edited by czardas

Share this post


Link to post
Share on other sites

interesting approach - but will be hard to enum that many variables.. the array im dealing with is nearly 4,000 records

Share this post


Link to post
Share on other sites

#5 ·  Posted (edited)

Enum doesn't effect the method. Just remove it and use the second array to track changes using numbers instead.

;

#include <Array.au3>

Local $aArray[10]

$aArray[0] = "Deleted"
$aArray[1] = "bob"
$aArray[2] = "larry"
$aArray[3] = "mark"
$aArray[4] = "will"
$aArray[5] = "pete"
$aArray[6] = "martha"
$aArray[7] = "jane"
$aArray[8] = "jill"
$aArray[9] = "jack"
_ArrayDisplay($aArray)

Local $aID[UBound($aArray)] ; Second array to track changes in $aArray

For $i = 1 To UBound($aID) -1
    $aID[$i] = $i ; Each element points to a value in $aArray
Next
;_ArrayDisplay($aID)

; Delete "pete"
$aID[5] = 0
For $i = 6 To UBound($aID) -1
    $aID[$i] -= 1
Next
_ArrayDelete($aArray, 5)
_ArrayDisplay($aArray)

; Access "jane"
MsgBox(0, "Access jane", $aArray[$aID[7]])

; Access "pete"
MsgBox(0, "Access pete", $aArray[$aID[5]])

I don't know if it's right for your project, but I sometimes do this kind of thing.

Edited by czardas

Share this post


Link to post
Share on other sites

gcue,

Are you talking about modifying the array at runtime or some kind of pre-processing approach?

If you need to maintain a count at offset +0 you can always use Ubound.

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

Share this post


Link to post
Share on other sites

gcue,

Are you talking about modifying the array at runtime or some kind of pre-processing approach?

If you need to maintain a count at offset +0 you can always use Ubound.

kylomas

pre-processing

did you mean something like this?

cant seem to get the syntax right - if its possible with this approach

#include <array.au3>


$msg_normal = 0


local $array[1]


$array[ReDim $array[UBound($array)+1]] = "bob"
$array[ReDim $array[UBound($array)+1]] = "larry"
$array[ReDim $array[UBound($array)+1]] = "mark"
$array[ReDim $array[UBound($array)+1]] = "will"
$array[ReDim $array[UBound($array)+1]] = "pete"
$array[ReDim $array[UBound($array)+1]] = "martha"
$array[ReDim $array[UBound($array)+1]] = "jane"
$array[ReDim $array[UBound($array)+1]] = "jill"
$array[ReDim $array[UBound($array)+1]] = "jack"
$array[ReDim $array[UBound($array)+1]] = "jim"


_ArrayDisplay($array)


Func Debug($variable1 = "", $variable2 = "", $variable3 = "")


;~  #include <array.au3>
;~  $msg_normal = 0


If IsArray($variable1) Then
_ArrayDisplay($variable1)
Else
If $variable2 <> "" Then
$variable1 &= @CRLF & $variable2
EndIf


If $variable3 <> "" Then
$variable1 &= @CRLF & $variable3
EndIf


ClipPut($variable1)
MsgBox($msg_normal, "Debug", $variable1)
EndIf


EndFunc   ;==>Debug

Share this post


Link to post
Share on other sites

Enum doesn't effect the method. Just remove it and use the second array to track changes using numbers instead.

;

#include <Array.au3>

Local $aArray[10]

$aArray[0] = "Deleted"
$aArray[1] = "bob"
$aArray[2] = "larry"
$aArray[3] = "mark"
$aArray[4] = "will"
$aArray[5] = "pete"
$aArray[6] = "martha"
$aArray[7] = "jane"
$aArray[8] = "jill"
$aArray[9] = "jack"
_ArrayDisplay($aArray)

Local $aID[UBound($aArray)] ; Second array to track changes in $aArray

For $i = 1 To UBound($aID) -1
    $aID[$i] = $i ; Each element points to a value in $aArray
Next
;_ArrayDisplay($aID)

; Delete "pete"
$aID[5] = 0
For $i = 6 To UBound($aID) -1
    $aID[$i] -= 1
Next
_ArrayDelete($aArray, 5)
_ArrayDisplay($aArray)

; Access "jane"
MsgBox(0, "Access jane", $aArray[$aID[7]])

; Access "pete"
MsgBox(0, "Access pete", $aArray[$aID[5]])

I don't know if it's right for your project, but I sometimes do this kind of thing.

the modifying of the array isnt occuring when the script runs...  its me manually typing in the changes before the script runs

Share this post


Link to post
Share on other sites

#9 ·  Posted (edited)

You might want to update again in the future. Until you know the exact contents of the array, you should use a method which allows changes to be made. You could also access the data using one of the two array search functions: then you wouldnt necessarily need to track changes.

Edited by czardas

Share this post


Link to post
Share on other sites

the data keeps changing.. so thats why the array changes (values get added or removed)

Share this post


Link to post
Share on other sites

#11 ·  Posted (edited)

I showed a way to delete an element and still access records using their original numeric identifier using the only method I know of. I thought that was what you wanted.

;

#include <Array.au3>

Local $aArray[10]

$aArray[0] = "Deleted"
$aArray[1] = "bob"
$aArray[2] = "larry"
$aArray[3] = "mark"
$aArray[4] = "will"
$aArray[5] = "pete"
$aArray[6] = "martha"
$aArray[7] = "jane"
$aArray[8] = "jill"
$aArray[9] = "jack"
;_ArrayDisplay($aArray)

Local $aID[UBound($aArray)] ; Second array to track changes in $aArray

For $i = 1 To UBound($aID) -1
    $aID[$i] = $i ; Each element points to a value in $aArray
Next
;_ArrayDisplay($aID)

; Delete pete
_DeleteElement($aArray, $aID, 5)
;_ArrayDisplay($aArray)

; Access jane
MsgBox(0, "Access jane", $aArray[$aID[7]])

; Access pete
MsgBox(0, "Access pete", $aArray[$aID[5]])

; Insert john ID = 10
_InsertElement($aArray, $aID, 3, "john") ; Insert John at third position
;_ArrayDisplay($aArray)

; Access jill
MsgBox(0, "Access jill", $aArray[$aID[8]])

; Access john
MsgBox(0, "Access john", $aArray[$aID[10]])

_ArrayDisplay($aArray)

Func _DeleteElement(ByRef $aArray, ByRef $aID, $iElement)
    $aID[$iElement] = 0
    For $i = $iElement +1 To UBound($aID) -1
        $aID[$i] -= 1
    Next
    _ArrayDelete($aArray, 5)
EndFunc

Func _InsertElement(ByRef $aArray, ByRef $aID, $iElement, $vValue)
    For $i = $iElement +1 To UBound($aID) -1
        $aID[$i] += 1
    Next
    _ArrayAdd($aID, $iElement)
    _ArrayInsert($aArray, $iElement, $vValue)
EndFunc
Edited by czardas

Share this post


Link to post
Share on other sites

ok.. so if i use the numbers.. and i delete record 5 for instance.. i have to re-write the numbers 6-9 to accomodate the change (6 becomes 5, 7 becomes 6, etc).. not an easy task when you have almost 4,000 records.

the modifications are occuring before i run the script.  i am manually removing/adding entries so the record numbers in the array will be wrong any time i do that.

sorry if i was not as clear

Share this post


Link to post
Share on other sites

#13 ·  Posted (edited)

In the code I posted you can access the elements from their original numeric identifier. You do not need to manually modify the array. Information about each new record is added to the end of the change-tracking array. Access the elements using the original numbers until you know the final version. Then hard code it if you want to. Otherwise you might want to use _ArraySearch() or _ArrayBinarySearch().

Edit: There was a mistake in the code - now fixed.

Edited by czardas

Share this post


Link to post
Share on other sites

Is it me or is that one more typical good use case for SQLite?

1 person likes this

This wonderful site allows debugging and testing regular expressions (many flavors available). An absolute must have in your bookmarks.
Another excellent RegExp tutorial. Don't forget downloading your copy of up-to-date pcretest.exe and pcregrep.exe here
RegExp tutorial: enough to get started
PCRE v8.33 regexp documentation latest available release and currently implemented in AutoIt beta.

SQLitespeed is another feature-rich premier SQLite manager (includes import/export). Well worth a try.
SQLite Expert (freeware Personal Edition or payware Pro version) is a very useful SQLite database manager.
An excellent eBook covering almost every aspect of SQLite3: a must-read for anyone doing serious work.
SQL tutorial (covers "generic" SQL, but most of it applies to SQLite as well)
A work-in-progress SQLite3 tutorial. Don't miss other LxyzTHW pages!
SQLite official website with full documentation (may be newer than the SQLite library that comes standard with AutoIt)

Share this post


Link to post
Share on other sites

interesting you bring that up... what i do is build a sqlite file from the array...

Share this post


Link to post
Share on other sites

#16 ·  Posted (edited)

Do the records have to be deleted, can they just be excluded from whatever you are doing with them next?  like,

#include <array.au3>


local $array[10]


$x = 0


$array[$x] = "bob"
$x +=1
$array[$x] = "larry"
$x +=1
$array[$x] = "mark"
$x +=1
$array[$x] = "will"
$x +=1
$array[$x] = "pete"
$x +=1
$array[$x] = "martha"
$x +=1
$array[$x] = "jane"
$x +=1
$array[$x] = "jill"
$x +=1
$array[$x] = "jack"
$x +=1
$array[$x] = "jim"


msgbox(0, '' , "9 is " & $array[9])   ; Jim is 9
$array = _deletefolk($array , "martha;will") 
_ArrayDisplay(_NoBlanks($array), "9 is " & $array[9])              ;Jim is still 9

Func _deletefolk($aArray, $sNames)
$aNames = stringsplit($sNames , ";" , 3)
for $i = 0 to ubound($aNames) - 1
$aFound = _ArrayFindAll($aArray , $aNames[$i])
$aArray[$aFound[0]] = ""
next

return $aArray

EndFunc

Func _NoBlanks($array)
return stringsplit(stringreplace(_ArrayToString($array) , "||" , "|"), "|" , 3)
EndFunc
Edited by boththose

,-. .--. ________ .-. .-. ,---. ,-. .-. .-. .-.
|(| / /\ \ |\ /| |__ __||| | | || .-' | |/ / \ \_/ )/
(_) / /__\ \ |(\ / | )| | | `-' | | `-. | | / __ \ (_)
| | | __ | (_)\/ | (_) | | .-. | | .-' | | \ |__| ) (
| | | | |)| | \ / | | | | | |)| | `--. | |) \ | |
`-' |_| (_) | |\/| | `-' /( (_)/( __.' |((_)-' /(_|
'-' '-' (__) (__) (_) (__)

Share this post


Link to post
Share on other sites

gcue,

We need more info on your app.  Otherwise the obvious answer is to populate SQLite with whatever method you are using to build the array.

If you want to stick with an array (maybe to minimize SQLite DB access) then you need a wrapper of some kind, probably similar to what czardas has shown.

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

Share this post


Link to post
Share on other sites

You can do something like this, and not worry about deleting/repopulating the array:

Local $aSomething[40][2]
; populate
For $i = 0 To UBound($aSomething)-1
    $aSomething[$i][0]=$i
    $aSomething[$i][1]=True
Next

; 'delete' some of the records (just make them False)
$aSomething[20][1]=False
$aSomething[25][1]=False

; loop through, and skip those that are false
For $i = 0 To UBound($aSomething)-1
    If $aSomething[$i][1] Then
        ConsoleWrite($aSomething[$i][0] & @CRLF)
    EndIf
Next
1 person likes this

IEbyXPATH-Grab IE DOM objects by XPATH IEscriptRecord-Makings of an IE script recorder ExcelFromXML-Create Excel docs without excel installed GetAllWindowControls-Output all control data on a given window.

Share this post


Link to post
Share on other sites
ok here's the scenario again i apologize if i have been unclear... i have an array being built in the code as shown below.  there are close to 4,000 records. 
 
#include <array.au3>


Local $array[10]


$array[0] = "bob"
$array[0] = "larry"
$array[2] = "mark"
$array[3] = "will"
$array[4] = "pete"
$array[5] = "martha"
$array[6] = "jane"
$array[7] = "jill"
$array[8] = "jack"
$array[9] = "jim"


_ArrayDisplay($array)
then when something changes and i have to add or delete some records - i have to delete the code for those records being created so the code looks like the code below after the changes.  it becomes a huge hassle when dealing with a large dataset
#include <array.au3>


Local $array[10]


$array[0] = "bob"
$array[2] = "mark"
$array[3] = "will"
$array[4] = "pete"
$array[5] = "martha"
$array[9] = "jim"


_ArrayDisplay($array)
 
thanks again for the help

Share this post


Link to post
Share on other sites

#20 ·  Posted (edited)

but in that example, those elements still exist.  If they were deleted the ubound would change.  It is the same as ignoring them, doesnt matter what the exclude string is.

#include <array.au3>


local $array[10]


$x = 0


$array[$x] = "bob"
$x +=1
$array[$x] = "larry"
$x +=1
$array[$x] = "mark"
$x +=1
$array[$x] = "will"
$x +=1
$array[$x] = "pete"
$x +=1
$array[$x] = "martha"
$x +=1
$array[$x] = "jane"
$x +=1
$array[$x] = "jill"
$x +=1
$array[$x] = "jack"
$x +=1
$array[$x] = "jim"


$array = _deletefolk($array , "larry;jane;jill;jack") 
_ArrayDisplay($array)


Func _deletefolk($aArray, $sNames)
$aNames = stringsplit($sNames , ";" , 3)
for $i = 0 to ubound($aNames) - 1
$aFound = _ArrayFindAll($aArray , $aNames[$i])
$aArray[$aFound[0]] = ""
next

return $aArray

EndFunc
Edited by boththose

,-. .--. ________ .-. .-. ,---. ,-. .-. .-. .-.
|(| / /\ \ |\ /| |__ __||| | | || .-' | |/ / \ \_/ )/
(_) / /__\ \ |(\ / | )| | | `-' | | `-. | | / __ \ (_)
| | | __ | (_)\/ | (_) | | .-. | | .-' | | \ |__| ) (
| | | | |)| | \ / | | | | | |)| | `--. | |) \ | |
`-' |_| (_) | |\/| | `-' /( (_)/( __.' |((_)-' /(_|
'-' '-' (__) (__) (_) (__)

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