Jump to content

Arrays... confusing!


tnok85
 Share

Recommended Posts

Alright... I've read through a bunch of posts/tutorials and the wiki, but I'm just not grasping it.

Basically, what I'm doing is this. There are a variable number of entries (which I can fetch at the beginning of the program - that's fine, got that down) that will each be the first entry in each of the array. For reference, I'm working with 82 entries right now.

So from those 82 entries, each is checked in a loop that looks for 19 attributes. I want each of those attributes inserted beneath the main entry.

Sort of like this....

A B C D E F (and so on to 82 entries right)

5 2 6 4 1 5

7 4 2 7 5 3

1 5 6 8 3 8

(and so on to 19 attributes down)

I have the loop to get the attributes for each down just fine, and am currently exporting them to text files that I can manually import to Excel, but that's really sub-optimal. I'd like to make one large array and export it all at once.

I don't need the code written for me... but any pointers in the right direction would be very greatly appreciated.

Link to comment
Share on other sites

#include <Array.au3>
Local $Array[82][20]

$Array[0][0] = "A"
$Array[0][1] = "5 2 6 4 1 5"
$Array[0][2] = "7 4 2 7 5 3"
$Array[0][3] = "1 5 6 8 3 8"
$Array[0][4] = "Attribute #4"
$Array[0][5] = "Attribute #5"
$Array[0][6] = "Attribute #6"
$Array[0][7] = "Attribute #7"
$Array[0][8] = "Attribute #8"
$Array[0][9] = "Attribute #9"
$Array[0][10] = "Attribute #10"
$Array[0][11] = "Attribute #11"
$Array[0][12] = "Attribute #12"
$Array[0][13] = "Attribute #13"
$Array[0][14] = "Attribute #14"
$Array[0][15] = "Attribute #15"
$Array[0][16] = "Attribute #16"
$Array[0][17] = "Attribute #17"
$Array[0][18] = "Attribute #18"
$Array[0][19] = "Attribute #19"
_ArrayDisplay($Array)

Link to comment
Share on other sites

#include <Array.au3>
Local $Array[82][20]

$Array[0][0] = "A"
$Array[0][1] = "5 2 6 4 1 5"
$Array[0][2] = "7 4 2 7 5 3"
$Array[0][3] = "1 5 6 8 3 8"
$Array[0][4] = "Attribute #4"
$Array[0][5] = "Attribute #5"
$Array[0][6] = "Attribute #6"
$Array[0][7] = "Attribute #7"
$Array[0][8] = "Attribute #8"
$Array[0][9] = "Attribute #9"
$Array[0][10] = "Attribute #10"
$Array[0][11] = "Attribute #11"
$Array[0][12] = "Attribute #12"
$Array[0][13] = "Attribute #13"
$Array[0][14] = "Attribute #14"
$Array[0][15] = "Attribute #15"
$Array[0][16] = "Attribute #16"
$Array[0][17] = "Attribute #17"
$Array[0][18] = "Attribute #18"
$Array[0][19] = "Attribute #19"
_ArrayDisplay($Array)

That's perfect, thanks! Then for the second entry, I just use [1][x] in the place of that. Makes so much sense when I actually see it.

Thank you. :)

To export a 2D array to excel you can use _ExcelWriteSheetFromArray look for it on the AutoIt Help.

Awesome - thanks. When I get to that point I'll look that up. ;) Edited by tnok85
Link to comment
Share on other sites

Alright, this is working great. The way I have it set up now (much more efficient) means I don't know the number ahead of time - but I know it's under 100 so I just declare the Array as [100][20], and the rest of the script ignores the empty slots. Exporting to Excel nicely.

Now what I want to do is compare each column to each other... reading up on min/max and such looks like it's only set up for a single dimension array.

For example, I want to compare [0][2] to [1][2] to [2][2] to [3][2] all the way down to [20][2], then [0][3] to [20][3] and so on... then it finds the largest and smallest numbers, then tells me which rows they are in from the original array.

I can imagine a way to do this by loading each column into a new array and doing a min/max search in there, getting the result, and comparing that to the original array. But I'm not sure if there's a more efficient (built-in) way to do this. Any advice?

Example:

Alpha       44  51  64  34
Beta        62  73  23  15
Charlie     12  24  73  23
Delta       23  32  12  23
Echo        77  45  34  55
Foxtrot     32  59  11  23

I want it to check for each column... so for the first numerical column, 12 (Charlie) is the lowest and 77 (Echo) is the highest. For the second, 24 (Charlie) is the lowest and Beta (73) is the highest. That's the information I want to get for each column.

Edited by tnok85
Link to comment
Share on other sites

Here is an illustration to show how you can use nested loops to populate or access the array elements. I had to reorganize your data to get the first row as headings. It is often better to use the first column for this purpose.

#include <Array.au3>

Local $aLetters[6] = ["A","B","C","D","E","F"] ; These are the main headings.
Local $aEntries[18] = ["5","7","1","2","4","5","6","2","6","4","7","8","1","5","3","5","3","8"] ; This is the data collected.

Local $aArray[4][6]
For $i = 0 To 5 ; Create the main headings.
    $aArray[0][$i] = $aLetters[$i]
Next

_ArrayDisplay($aArray, "Main Headings")

; Insert the numbers under the main headings
$a = 0
For $i = 0 To 5 ; For each heading
    For $j = 1 To 3 ; Add the data to each row
        $aArray[$j][$i] = $aEntries[$a]
        $a += 1
    Next
Next

_ArrayDisplay($aArray, "After Adding Data")

; Find Max Value by looping through the array.
$iMax = 0
For $i = 0 To 5 ; Under each heading
    For $j = 1 To 3 ; Compair the data in each row
        If $aArray[$j][$i] > $iMax Then $iMax = $aArray[$j][$i]
    Next
Next
MsgBox(0, "Max Value", $iMax)

Edit

I have added some extra lines of code to show how you can get the max value by looping through the array.

Edited by czardas
Link to comment
Share on other sites

Here is an illustration to show how you can use nested loops to create or access the array elements. I had to reorganize your data to get the first row as headings. It is often better to use the first column for this purpose.

#include <Array.au3>

Local $aLetters[6] = ["A","B","C","D","E","F"] ; These are the main headings.
Local $aEntries[18] = ["5","7","1","2","4","5","6","2","6","4","7","8","1","5","3","5","3","8"] ; This is the data collected.

Local $aArray[4][6]
For $i = 0 To 5 ; Create the main headings.
    $aArray[0][$i] = $aLetters[$i]
Next

_ArrayDisplay($aArray, "Main Headings")

; Insert the numbers under the main headings
$a = 0
For $i = 0 To 5 ; For each heading
    For $j = 1 To 3 ; Add the data to each row
        $aArray[$j][$i] = $aEntries[$a]
        $a += 1
    Next
Next

_ArrayDisplay($aArray, "After Adding Data")

So with this method, my first array would be $aLetters[82] and $aEntries[1640].... since it's 82 x 20.

I'm actually already using headings. The first column [0] in my array is the name of a location. The following column [1] is a status of that location. The data I want to access and compare is [2] through [19], but not to each other - I want to test all the [x][2]'s and [x][3]'s etc.

Here's an actual output example from _ArrayDisplay - this goes on to 82, but this is the first 10 locations with all the sections I need compared vertically.

I manually formatted it a bit to fit well here.

[0]         [1]        [2]   [3]   [4]   [5]    [6]    [7]   [8]   [9]   [10]  [11]  [12]  [13]  [14]  [15]   [16]   [17]   [18]   [19]
[0] |Alpha      |uncommon|31.80|60.40|40.00|115.00|60.00 |75.00|40.00|65.00|42.00|45.50|40.00|57.50|45.00|126.00|104.00|112.50|125.00|117.00
[1] |Beta       |uncommon|48.90|82.00|50.00|110.00|42.00 |63.00|32.50|82.50|38.50|38.50|64.00|70.00|53.00|162.00|84.00 |90.00 |130.00|103.50
[2] |Charlie    |uncommon|39.00|65.20|40.00|130.00|48.00 |81.00|25.00|67.50|38.50|49.00|44.00|70.00|60.50|156.00|92.00 |121.50|115.00|90.00
[3] |Delta      |uncommon|30.00|60.40|42.00|120.00|96.00 |81.00|37.50|72.50|45.50|49.00|52.00|55.00|60.50|144.00|92.00 |99.00 |100.00|108.00
[4] |Foxtrot    |uncommon|33.90|65.20|70.00|135.00|84.00 |78.00|50.00|75.00|38.50|63.00|44.00|80.00|56.50|180.00|112.00|121.50|135.00|126.00
[5] |Golf       |frequent|71.40|88.40|44.00|125.00|60.00 |72.00|35.00|82.50|35.00|38.50|40.00|75.00|50.00|132.00|76.00 |117.00|140.00|103.50
[6] |Hotel      |uncommon|33.90|88.40|56.00|110.00|78.00 |90.00|52.50|77.50|31.50|49.00|36.00|70.00|75.50|138.00|112.00|135.00|115.00|130.50
[7] |India      |uncommon|61.50|76.00|48.00|125.00|36.00 |75.00|32.50|75.00|35.00|35.00|36.00|52.50|53.00|126.00|96.00 |99.00 |115.00|99.00
[8] |Juliet     |uncommon|61.50|76.00|42.00|115.00|30.00 |48.00|35.00|82.50|45.50|49.00|40.00|67.50|75.50|132.00|96.00 |81.00 |95.00 |126.00
[9] |Kilo       |uncommon|52.80|65.20|52.00|100.00|36.00 |78.00|30.00|75.00|35.00|45.50|28.00|62.50|60.50|114.00|92.00 |112.50|110.00|103.50
[10]|Lima       |uncommon|30.00|70.40|42.00|110.00|132.00|87.00|47.50|65.00|42.00|80.50|40.00|67.50|70.00|114.00|96.00 |90.00 |110.00|103.50

So for example, from row [2], I want the script to tell me that cols [3] and [10] have the lowest numbers (30.00) and [5] has the highest number (71.40).

Edited by tnok85
Link to comment
Share on other sites

So with this method, my first array would be $aLetters[82] and $aEntries[1640].... since it's 82 x 20.

Well yes, but realize that my script was just an example of nested loops. How you actually add the entries depends on the order you get them. You will have to figure out the best way to do that. In the last example, the names (Alpha, Beta etc...) are in the first column, which is standard. I have edited my script above to show a way to get the max value. Edited by czardas
Link to comment
Share on other sites

Well yes, but realize that my script was just an example of nested loops. How you actually add the entries depends on the order you get them. You will have to figure out the best way to do that. In the last example, the names (Alpha, Beta etc...) are in the first column, which is standard. I have edited my script above to show a way to get the max value.

So what I want isn't entirely possible in a 2D Array? I'll either need to nest them in somehow or go through the process of reading each value from the array row and comparing them? I can do the latter, it just seems cumbersome.

Link to comment
Share on other sites

So what I want isn't entirely possible in a 2D Array? I'll either need to nest them in somehow or go through the process of reading each value from the array row and comparing them? I can do the latter, it just seems cumbersome.

The function _ArrayMax works in the same way: ie by looping through a one dimensional array. Sometimes you may only want to compair elements from part of the array. If you intend to compair the elements more than once, then it is best to create a function to find the maximum value in a two dimensional array, and call on that in your main script. That way you get less lines of code.
Link to comment
Share on other sites

The function _ArrayMax works in the same way: ie by looping through a one dimensional array. Sometimes you may only want to compair elements from part of the array. If you intend to compair the elements more than once, then it is best to create a function to find the maximum value in a two dimensional array, and call on that in your main script. That way you get less lines of code.

Aha... so I can use it to compare one dimension of a multi-dimensional array. Thank you, I'll start looking into this.

Link to comment
Share on other sites

Aha... so I can use it to compare one dimension of a multi-dimensional array. Thank you, I'll start looking into this.

No that's not what I meant to say. I meant you will need another function to find the maximum value in a two dimensional array. Try this:

#include <Array.au3>

Local $aLetters[6] = ["A","B","C","D","E","F"] ; These are the main headings.
Local $aEntries[18] = ["5","7","1","2","4","5","6","2","6","4","7","8","1","5","3","5","3","8"] ; This is the data collected.

Local $aArray[4][6]
For $i = 0 To 5 ; Create the main headings.
    $aArray[0][$i] = $aLetters[$i]
Next

; Insert the numbers under the main headings
$a = 0
For $i = 0 To 5 ; For each heading
    For $j = 1 To 3 ; Add the data to each row
        $aArray[$j][$i] = $aEntries[$a]
        $a += 1
    Next
Next

_ArrayDisplay($aArray, "After Adding Data")

$iVal = _FindArrayMaxValue($aArray, 1) ; Start compairing from row 1.
MsgBox(0, "Max Value", $iVal)

; Function to find the max value in a 2D array
Func _FindArrayMaxValue($a_Array, $iRowStart = 0, $iColStart = 0, $iRowStop = -1, $iColStop = -1)
    If Not UBound($a_Array, 2) Or UBound($a_Array, 3) Then Return SetError(1, 0, 0)
    If $iRowStop < 0 Then $iRowStop = UBound($a_Array, 1) -1
    If $iColStop < 0 Then $iColStop = UBound($a_Array, 2) -1
    If ($iRowStart < 0) Or ($iColStart < 0) Or ($iRowStart > $iRowStop) Or ($iColStart > $iColStop) Then Return SetError(2, 0, 0)
    Local $iMax = 0
    For $i = $iRowStart To $iRowStop
        For $j = $iColStart To $iColStop
            If $a_Array[$i][$j] > $iMax Then $iMax = $a_Array[$i][$j]
        Next
    Next
    Return $iMax
EndFunc
Edited by czardas
Link to comment
Share on other sites

Here is a quick function to find the maximum value and its' index in a multidimensional array

#include <Array.au3>

Local $Array[82][20]
Local $aLetters[6] = ["A", "B", "C", "D", "E", "F"] ; These are the main headings.
Local $aEntries[18] = ["5", "7", "1", "2", "4", "5", "6", "2", "6", "4", "7", "8", "1.3", "5", "3", "5", "3", "8"] ; This is the data collected.

For $i = 0 To UBound($aLetters) - 1
    $Array[$i][0] = $aLetters[$i]
    For $b = 0 To UBound($aEntries) - 1
        $Array[$i][$b + 1] = $aEntries[$b]
    Next
Next

_ArrayDisplay($Array)

$Max = _ArrayMaximum($Array, 13)
If Not @error Then MsgBox(262208, 'SUCCESS', 'Max Value is ' & $Max & ' at index ' & @extended)


;Quick Example, Successful Returns The Maximum Value And @Extended Stores The Index Of That Value (Ties Go To Last Index Found)
;Default Search Is Numeric
;On Error, Sets @Error To 1
Func _ArrayMaximum($iArray, $Column, $Numeric = True)
    Local $Maxval, $IndexofVal
    If Not IsArray($iArray) Then Return 1
    For $i = 0 To UBound($iArray) - 1
        If Not $iArray[$i][$Column] Then ContinueLoop
        Switch $Numeric
            Case True
                If Number($iArray[$i][$Column]) >= $Maxval Then
                    $Maxval = $iArray[$i][$Column]
                    $IndexofVal = $i
                Else
                EndIf
            Case False
                If $iArray[$i][$Column] >= $Maxval Then
                    $Maxval = $iArray[$i][$Column]
                    $IndexofVal = $i
                EndIf
        EndSwitch
    Next
    If $Maxval And $IndexofVal Then
        SetExtended($IndexofVal)
        Return $Maxval
    EndIf
    SetError(1)
EndFunc   ;==>_ArrayMaximum
Edited by Varian
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...