Jump to content

Split Array from 2D to 4D - SOLVED


dm83737
 Share

Recommended Posts

I have looked at all the array scripts I could find in these forums, as well as all the array and string functions in the help file, and I could not come up with anything that would get what I want done, completed.

I have numbers that correlate to times (i.e. - 00:00:00, 104:34:21, etc.) and currently they are being returned within an array that would look like so:

#include <Array.au3>

Local $avArray[4][1]

$avArray[0][0] = "00:00:00"
$avArray[1][0] = "22:23:51"
$avArray[2][0] = "39:34:58"
$avArray[3][0] = "101:41:22"

_ArrayDisplay($avArray, "Times")

How do I split these from 2D to 4D by the ":" symbol to make it look like this:

#include <Array.au3>

Local $avArray[4][3]

$avArray[0][0] = "00"
$avArray[0][1] = "00"
$avArray[0][2] = "00"
$avArray[1][0] = "22"
$avArray[1][1] = "23"
$avArray[1][2] = "51"
$avArray[2][0] = "39"
$avArray[2][1] = "34"
$avArray[2][2] = "58"
$avArray[3][0] = "101"
$avArray[3][1] = "41"
$avArray[3][2] = "22"

_ArrayDisplay($avArray, "Times")

I have a feeling it is a "For $i = 1 To UBound***" type statement, but am unable to format it correctly.

Thanks for the help

Edited by dm83737
Link to comment
Share on other sites

  • Moderators

dm83737,

Your feeling was quite correct! Take a look at this:

#include <Array.au3>

Local $avArray[4]    ; Why make this array 2D?  

$avArray[0] = "00:00:00"
$avArray[1] = "22:23:51"
$avArray[2] = "39:34:58"
$avArray[3] = "101:41:22"

Local $avNewArray[4][3]

For $i = 0 To UBound($avArray) - 1
    $avTempArray = StringSplit($avArray[$i], ":")
    For $j = 0 To 2
        $avNewArray[$i][$j] = $avTempArray[$j + 1]
    Next
Next

_ArrayDisplay($avNewArray)

I hope this does what you want.

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

#include <Array.au3>

Local $avArray[4]    ; Why make this array 2D?  

$avArray[0] = "00:00:00"
$avArray[1] = "22:23:51"
$avArray[2] = "39:34:58"
$avArray[3] = "101:41:22"

Local $avNewArray[4][3]

For $i = 0 To UBound($avArray) - 1
    $avTempArray = StringSplit($avArray[$i], ":")
    For $j = 0 To 2
        $avNewArray[$i][$j] = $avTempArray[$j + 1]
    Next
Next

_ArrayDisplay($avNewArray)

Of course, mine does not work quite as well as yours... When I try to implement what you have given me into my script, it seems to clear out the index above the one it writes to (i.e. - If it is in the process of writing the "39 | 34 | 58" line to the 3 columns, it clears out the row above it, "22 | 23 | 51").

I am attaching the file I am reading and the full script so you can see exactly what it is that leads up to this situation. Thanks again for your help!

Cue Sheet Time Scraper.au3

CrazyCousinz-EssentialMix-2009-09-12.zip

Link to comment
Share on other sites

What is the inner (j) loop meant to do?

StringSplit() already expands each member of the 1st dimension into the 2nd one.

Hopefully Melba23 can answer that as I am a bit inadequate when it comes to Arrays...

I spoke too soon, when I place -ArrayDisplay's in the script from Melba23, the temp array holds the 3 entries from that row and then the next 'For $i' function places them in the correct order in a new array and continues to build from there.

#include <Array.au3>

Local $avArray[4]    ; Why make this array 2D?

$avArray[0] = "00:00:00"
$avArray[1] = "22:23:51"
$avArray[2] = "39:34:58"
$avArray[3] = "101:41:22"

_ArrayDisplay($avArray, "Initial Array")

Local $avNewArray[4][3]

For $i = 0 To UBound($avArray) - 1
    $avTempArray = StringSplit($avArray[$i], ":")
    _ArrayDisplay($avTempArray, "Temp Array")
    For $j = 0 To 2
        $avNewArray[$i][$j] = $avTempArray[$j + 1]
        _ArrayDisplay($avNewArray, "New Array")
    Next
Next

_ArrayDisplay($avNewArray)
Edited by dm83737
Link to comment
Share on other sites

  • Moderators

memoryoverflow,

StringSplit certainly does NOT "expand each member of the 1st dimension into the 2nd one" - it merely creates an independent array of the separate numbers within each element of $avArray. We need to move these elements into the relevant elements of the new array.

; Take each element of the initial array
For $i = 0 To UBound($avArray) - 1
        ; Extract the contents into a temporary array
    $avTempArray = StringSplit($avArray[$i], ":")
        ; $avTempArray will now have 4 elements
        ; [0] 3
        ; [1] hours
        ; [2] minutes
        ; [3] seconds
        ; The relevant elements of $avNewarray are still empty at this point
        ; So we need to transfer the elements of $avTempArray to the relevant elements of $avNewArray
    For $j = 0 To 2
            ; We move through the [1]-[3] elements of $avTempArray and put them into the correct elements of $avNewArray
        $avNewArray[$i][$j] = $avTempArray[$j + 1]
    Next
Next

Does it make sense now? :D

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

StringSplit certainly does NOT "expand each member of the 1st dimension into the 2nd one" - it merely creates an independent array of the separate numbers within each element of $avArray. We need to move these elements into the relevant elements of the new array...

Does it make sense now? :D

Sure, now I see that you inserted that counter field for whatever reason. That was the part I missed.

What I still don't get: What is the difference between

each array element (of first dimension) containing an array and

each array element (of first dimension) containing an independent array?

(independent from what?)

*oops* might have misread it again - StringSplit itself inserts that counter?

Have to test it again - and wonder why it worked in my test script without further actions.

Ahh - just seen it, I use StringSplit with flag 2! That eases the matter considerably:

For $i = 0 To UBound($avArray) - 1
    $avArray[$i] = StringSplit($avArray[$i], ":", 2)
Next
should yield the same as your double-loop.
Edited by memoryoverflow

(The signature is placed on the back of this page to not disturb the flow of the thread.)

Link to comment
Share on other sites

  • Moderators

memoryoverflow,

There is no way StringSplit can insert the elements from $avArray directly into $avNewArray - unless I have completely misunderstood how StringSplit works! You cannot just use:

$avNewArray[0] = StringSplit[$avArray[0], ":")

1. Because because you will just get an array within an array element ($avNewArray[0]) and not 3 elements of a 2-D array ($avNewArray[0][0], [0][1] and [0][2]), and

2. You have already declared $avNewArray as a 2D array - and so you will get an error.

This should help you see what I mean:

#include <Array.au3>

Local $avArray[1]

$avArray[0]= "00:00:00"

Local $avNewArray[1][3]

$avNewArray[0][0] = StringSplit($avArray[0], ":")

; Look at the whole of the NewArray
_ArrayDisplay($avNewArray)
; Now look at the first element only
_ArrayDisplay($avNewArray[0][0])

That is why you need the $avTempArray and why you need the $j loop code. The whole thing works thus:

$avArray[0] = "00:00:00"
$avArray[1] = "22:23:51"
$avArray[2] = "39:34:58"
$avArray[3] = "101:41:22"

$avNewArray[0][0] = ""
$avNewArray[0][1] = ""
$avNewArray[0][2] = ""
$avNewArray[1][0] = ""
$avNewArray[1][1] = ""
$avNewArray[1][2] = ""
$avNewArray[2][0] = ""
$avNewArray[2][1] = ""
$avNewArray[2][2] = ""
$avNewArray[3][0] = ""
$avNewArray[3][1] = ""
$avNewArray[3][2] = ""


For $i = 0 To UBound($avArray) - 1
    ; First pass we are looking at $avArray[0]
    $avTempArray = StringSplit($avArray[$i], ":")
    ; So $avTempArray looks like
    ; [0] 3
    ; [1] 00
    ; [2] 00
    ; [3] 00
    ; We now move these elements into the relevant elements of $avNewArray
    For $j = 0 To 2
        $avNewArray[$i][$j] = $avTempArray[$j + 1]
        ; Which gives
        ; $avNewArray[0][0] = $avTempArray[1]
        ; $avNewArray[0][1] = $avTempArray[2]
        ; $avNewArray[0][2] = $avTempArray[3]
        ; And AavNewArray now reads
        $avNewArray[0][0] = "00"
        $avNewArray[0][1] = "00"
        $avNewArray[0][2] = "00"
        $avNewArray[1][0] = ""
        $avNewArray[1][1] = ""
        $avNewArray[1][2] = ""
        $avNewArray[2][0] = ""
        $avNewArray[2][1] = ""
        $avNewArray[2][2] = ""
        $avNewArray[3][0] = ""
        $avNewArray[3][1] = ""
        $avNewArray[3][2] = ""
        
    ; Second pass we are looking at $avArray[1]
    $avTempArray = StringSplit($avArray[$i], ":")
    ; So $avTempArray looks like
    ; [0] 3
    ; [1] 22
    ; [2] 23
    ; [3] 51
    ; We now move these elements into the relevant elements of $avNewArray
    For $j = 0 To 2
        $avNewArray[$i][$j] = $avTempArray[$j + 1]
        ; Which gives
        ; $avNewArray[1][0] = $avTempArray[1]
        ; $avNewArray[1][1] = $avTempArray[2]
        ; $avNewArray[1][2] = $avTempArray[3]
        ; And AavNewArray now reads
        $avNewArray[0][0] = "00"
        $avNewArray[0][1] = "00"
        $avNewArray[0][2] = "00"
        $avNewArray[1][0] = "22"
        $avNewArray[1][1] = "23"
        $avNewArray[1][2] = "51"
        $avNewArray[2][0] = ""
        $avNewArray[2][1] = ""
        $avNewArray[2][2] = ""
        $avNewArray[3][0] = ""
        $avNewArray[3][1] = ""
        $avNewArray[3][2] = ""
        
    ; And so on for the 3rd and 4th passes  
    Next
Next

But please do post your test script which works "without further actions" - I am always happy to learn. :D

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

I have already posted it just above your newest post.

And it works on my machine like expected.

Ok, now I see what you're at: Will post the complete thing with its surrounding (self contained runable) in a few minutes.

Edited by memoryoverflow

(The signature is placed on the back of this page to not disturb the flow of the thread.)

Link to comment
Share on other sites

Hi Melba

I know now what you mean with "independant" arrays.

StringSplit() acts like I expected, and you can work with the arrays it produces in each element of the 1-dimensional array, but...

you can not address them one by one.

The script, in which it worked for me, uses these arrays only internally. Trying to isolate the relevant part for this thread and addressing the 2nd-dimesion elements individually failed.

(But these are the things I percieve as inconsistent in respect to array handling.)

Anyway, it's given me the opportunity to be warned and not to relate on implicite arrays always or in all respects working like I expect them to.

(The signature is placed on the back of this page to not disturb the flow of the thread.)

Link to comment
Share on other sites

I have looked at all the array scripts I could find in these forums, as well as all the array and string functions in the help file, and I could not come up with anything that would get what I want done, completed.

I have numbers that correlate to times (i.e. - 00:00:00, 104:34:21, etc.) and currently they are being returned within an array that would look like so:

#include <Array.au3>

Local $avArray[4][1]

$avArray[0][0] = "00:00:00"
$avArray[1][0] = "22:23:51"
$avArray[2][0] = "39:34:58"
$avArray[3][0] = "101:41:22"

_ArrayDisplay($avArray, "Times")

How do I split these from 2D to 4D by the ":" symbol to make it look like this:

#include <Array.au3>

Local $avArray[4][3]

$avArray[0][0] = "00"
$avArray[0][1] = "00"
$avArray[0][2] = "00"
$avArray[1][0] = "22"
$avArray[1][1] = "23"
$avArray[1][2] = "51"
$avArray[2][0] = "39"
$avArray[2][1] = "34"
$avArray[2][2] = "58"
$avArray[3][0] = "101"
$avArray[3][1] = "41"
$avArray[3][2] = "22"

_ArrayDisplay($avArray, "Times")

I have a feeling it is a "For $i = 1 To UBound***" type statement, but am unable to format it correctly.

Thanks for the help

#include <Array.au3>






$Array = String_Split("00:00:00,22:23:51,39:34:58,101:41:22",",",":")

_ArrayDisplay($Array, "Times")

Func String_Split($string ,$delimiters1 ,$delimiters2)
$Array1 = StringSplit ( $string, $delimiters1)
Dim $MAXUBound = 0 , $OutArray2[1][1]
For $I = 1 To $Array1[0] Step 1
$OutArray =  StringSplit ( $Array1[$i], $delimiters2)
if $MAXUBound < $OutArray[0] Then 
ReDim $OutArray2[$i][$OutArray[0]]
$MAXUBound = $OutArray[0]
Else
ReDim $OutArray2[$i][UBound($OutArray2,2)]
EndIf
For $j = 1 To $OutArray[0] Step 1
$OutArray2[$i - 1][$j - 1] = $OutArray[$j]
Next
Next
Return $OutArray2
EndFunc

صرح السماء كان هنا

 

Link to comment
Share on other sites

  • Moderators

memoryoverflow,

For $i = 0 To UBound($avArray) - 1

$avArray[$i] = StringSplit($avArray[$i], ":", 2)

Next

should yield the same as your double-loop.

is not true.

Your method produces a pseudo-2D array - a set of arrays within the initial array - each 1D element of the $avArray array holding another 1D array with the elements produced by StringSplit.

The big problem is that, as you have found, you cannot address these internal elements individually - or at least I do not know a way short of extracting the internal array into temporary storage.

Using $avTempArray and the $j loop enables the creation of a real 2D array in which each element can be addressed individually.

If you do decide to stick with your method, you also need to bear in mind the warning in the Help file (under Language Reference - Variables)

"Especially the use of an Array inside another Array will severely affect the execution speed of your script".

I hope we have got that all cleared up now. :D

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

#include <Array.au3>

$Array = String_Split("00:00:00,22:23:51,39:34:58,101:41:22",",",":")
_ArrayDisplay($Array, "Times")

Func String_Split($string ,$delimiters1 ,$delimiters2)
   $Array1 = StringSplit ( $string, $delimiters1)
   Dim $MAXUBound = 0 , $OutArray2[1][1]

   For $I = 1 To $Array1[0] Step 1
      $OutArray =  StringSplit ( $Array1[$i], $delimiters2)

      If $MAXUBound < $OutArray[0] Then 
         ReDim $OutArray2[$i][$OutArray[0]]
         $MAXUBound = $OutArray[0]
      Else
         ReDim $OutArray2[$i][UBound($OutArray2,2)]
      EndIf

      For $j = 1 To $OutArray[0] Step 1
         $OutArray2[$i - 1][$j - 1] = $OutArray[$j]
      Next

   Next

Return $OutArray2

EndFunc

BRILLIANT! This worked like a champ!

Thanks a lot everyone for the solutions / lessons; any knowledge is good knowledge in my book.

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