Sign in to follow this  
Followers 0
JohnOne

Parsing/converting array!

13 posts in this topic

I have had total brain block on this for almost a week, I simply cannot get my head around the logic.

Asking if someone else can.

It does not look like a difficult problem, but I'm simply psychoblocked on the matter.

Bigger issue, which boils down to creating one array from another.

The two arrays below are what I start with and what I need to get to programmatically.

I'm seriously, usually fine and unafraid of arrays and this sort of logic, and don't understand why I'm suffering this mental block.

Please help a man in distress.

#include <Array.au3>

; In the following array, you see that Type1 one has 3 SubTypes,
; Subtype1, Subtype2, and Subtype3.
;
; Type 2 has 2 subtypes, type3, only 1 etc...
;
; Of course this is not fixed size array and the anount of subtypes vary
; The array is sorted by type though

Global $aFirstArray[10][2] = [["Type1", "Subtype1"],["Type1", "Subtype2"], _
        ["Type1", "Subtype3"],["Type2", "Subtype4"], _
        ["Type2", "Subtype5"],["Type3", "Subtype5"], _
        ["Type4", "Subtype6"],["Type4", "Subtype7"], _
        ["Type5", "Subtype8"],["Type5", "Subtype9"]]

_ArrayDisplay($aFirstArray, "This")


; This is the desired output array
; Like a Parent(Type) header, then Children (Subtypes) bel;ow it

Global $aSecondArray[15] = ["Type1", "Subtype1", "Subtype2", "Subtype3", _
        "Type2", "Subtype4", "Subtype5", _
        "Type3", "Subtype5", _
        "Type4", "Subtype6", "Subtype7", _
        "Type5", "Subtype8", "Subtype9"]

_ArrayDisplay($aSecondArray, "To This")

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



#2 ·  Posted (edited)

#include <Array.au3>

; In the following array, you see that Type1 one has 3 SubTypes,
; Subtype1, Subtype2, and Subtype3.
;
; Type 2 has 2 subtypes, type3, only 1 etc...
;
; Of course this is not fixed size array and the anount of subtypes vary
; The array is sorted by type though

Global $aFirstArray[10][2] = [["Type1", "Subtype1"],["Type1", "Subtype2"], _
        ["Type1", "Subtype3"],["Type2", "Subtype4"], _
        ["Type2", "Subtype5"],["Type3", "Subtype5"], _
        ["Type4", "Subtype6"],["Type4", "Subtype7"], _
        ["Type5", "Subtype8"],["Type5", "Subtype9"]]

_ArrayDisplay($aFirstArray, "This")


; This is the desired output array
; Like a Parent(Type) header, then Children (Subtypes) bel;ow it


Global $aSecondArray[0]

$lasttype = ""
for $i = 0 to ubound($aFirstArray) - 1

    $type = $aFirstArray[$i][0]

    If $type = $lasttype then
        _ArrayAdd($aSecondArray , $aFirstArray[$i][1])
    Else
        _ArrayAdd($aSecondArray , $aFirstArray[$i][0])
        _ArrayAdd($aSecondArray , $aFirstArray[$i][1])
    EndIf

    $lasttype = $type

next

    _ArrayDisplay($aSecondArray, "To This")

**This is totally assuming the first array is sorted by type as in the example

Edited by boththose
1 person likes this

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

Share this post


Link to post
Share on other sites

quite easy also using _ArrayUniqe and _ArrayFindAll
(bonus: there is no need to sort by Type)

#include <Array.au3>

; In the following array, you see that Type1 one has 3 SubTypes,
; Subtype1, Subtype2, and Subtype3.
;
; Type 2 has 2 subtypes, type3, only 1 etc...
;
; Of course this is not fixed size array and the anount of subtypes vary
; The array is sorted by type though

Global $aFirstArray[10][2] = [["Type1", "Subtype1"],["Type1", "Subtype2"], _
        ["Type1", "Subtype3"],["Type2", "Subtype4"], _
        ["Type2", "Subtype5"],["Type3", "Subtype5"], _
        ["Type4", "Subtype6"],["Type4", "Subtype7"], _
        ["Type5", "Subtype8"],["Type5", "Subtype9"]]

_ArrayDisplay($aFirstArray, "This")

Local $aTypes = _ArrayUnique($aFirstArray) ; list of single types that are in the $aFirstArray
Local $aWantedArray[UBound($aFirstArray) + $aTypes[0]] ; make room for output. All subtypes + single Types
Local $aSubTypesNdx, $iPointer = 0 ; internal use
;
For $i = 1 To $aTypes[0]
    $aSubTypesNdx = _ArrayFindAll($aFirstArray, $aTypes[$i]) ; find all subtypes of the same type
    $aWantedArray[$iPointer] = $aTypes[$i] ; header for next subtypes
    $iPointer += 1 ; point to next free element
    For $iSubtype = 0 To UBound($aSubTypesNdx) - 1 ; peek all subtypes
        $aWantedArray[$iPointer] = $aFirstArray[$aSubTypesNdx[$iSubtype]][1] ; populate output
        $iPointer += 1 ; point to next free element
    Next
    ; _ArrayDisplay($aWantedArray) ; shows WantedArray while is populated
Next
_ArrayDisplay($aWantedArray, "To This")
1 person likes this

small minds discuss people average minds discuss events great minds discuss ideas.... and use AutoIt....

Share this post


Link to post
Share on other sites

#4 ·  Posted (edited)

Same idea than boththose, without _Array functions (but the array must be sorted for it works).

#Include <Array.au3>

Local $aFirstArray[10][2] = [["Type1", "Subtype1"],["Type1", "Subtype2"], _
        ["Type1", "Subtype3"],["Type2", "Subtype4"], _
        ["Type2", "Subtype5"],["Type3", "Subtype5"], _
        ["Type4", "Subtype6"],["Type4", "Subtype7"], _
        ["Type5", "Subtype8"],["Type5", "Subtype9"]]
        
Local $aResult[ UBound($aFirstArray) * 2], $sLast, $n = 0

For $i = 0 To UBound($aFirstArray) - 1
    If $aFirstArray[$i][0] <> $sLast Or $n = 0 Then
        $sLast = $aFirstArray[$i][0]
        $aResult[$n] = $sLast
        $n += 1
        $aResult[$n] = $aFirstArray[$i][1]
    Else
        $aResult[$n] = $aFirstArray[$i][1]
    EndIf
    $n += 1
Next
Redim $aResult[$n]

_ArrayDisplay($aResult)

An other idea could be to use a SQLite memory database, (interesting for a big array, I think).

Edited by jguinch
1 person likes this

Share this post


Link to post
Share on other sites

#5 ·  Posted (edited)

you inspired me:  without arrayadds or redim - still needs the sorting on the first array

#include <Array.au3>


Global $aFirstArray[10][2] = [["Type1", "Subtype1"],["Type1", "Subtype2"], _
        ["Type1", "Subtype3"],["Type2", "Subtype4"], _
        ["Type2", "Subtype5"],["Type3", "Subtype5"], _
        ["Type4", "Subtype6"],["Type4", "Subtype7"], _
        ["Type5", "Subtype8"],["Type5", "Subtype9"]]

_ArrayDisplay($aFirstArray, "This")


; This is the desired output array
; Like a Parent(Type) header, then Children (Subtypes) bel;ow it


Global $sFinal = ""

$lasttype = ""
for $i = 0 to ubound($aFirstArray) - 1

    $type = $aFirstArray[$i][0]

    If $type = $lasttype then
        $sFinal &= $aFirstArray[$i][1] & ","
    Else
        $sFinal &=  $aFirstArray[$i][0] & ","
        $sFinal &=  $aFirstArray[$i][1] & ","
    EndIf

    $lasttype = $type

next

    $aFinal = stringsplit(stringtrimright($sFinal , 1), "," , 2)
    _ArrayDisplay($aFinal)
Edited by boththose
1 person likes this

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

Share this post


Link to post
Share on other sites

#7 ·  Posted (edited)

In my project, the subtypes also have values.

In the script below I'm adding those values, but means I'm looping through array twice

For bonus internet points, can anyone figure a way to incorporate both loops?

#include <Array.au3>


Global $aFirstArray[10][3] = [["Type1", "Subtype1", 10],["Type1", "Subtype2", 20], _
        ["Type1", "Subtype3", 30],["Type2", "Subtype4", 40], _
        ["Type2", "Subtype5", 50],["Type3", "Subtype5", 60], _
        ["Type4", "Subtype6", 70],["Type4", "Subtype7", 80], _
        ["Type5", "Subtype8", 90],["Type5", "Subtype9", 100]]


_ArrayDisplay($aFirstArray)

Local $aResult[UBound($aFirstArray) * 2][2], $sLast, $n = 0

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

    If $aFirstArray[$i][0] <> $sLast Or $n = 0 Then

        $sLast = $aFirstArray[$i][0]
        $aResult[$n][0] = $sLast ; Add Type to array
        $n += 1
        $aResult[$n][0] = $aFirstArray[$i][1] ; Add Subtype to array
        $aResult[$n][1] = $aFirstArray[$i][2] ; Add Value to array
    Else

        $aResult[$n][0] = $aFirstArray[$i][1] ; Add Subtype to array
        $aResult[$n][1] = $aFirstArray[$i][2] ; Add Value to array
    EndIf
    $n += 1

Next
ReDim $aResult[$n][2]

_ArrayDisplay($aResult)


; Adding The values of subtypes
$iTotalIndex = 0
$iTotalValue = 0

For $i = 1 To UBound($aResult) - 1
    If $aResult[$i][1] <> "" Then
        $iTotalValue += $aResult[$i][1] ; Add value of Subtype
    Else
        $aResult[$iTotalIndex][1] = $iTotalValue ; Insert total of subtype values into parent type
        $iTotalValue = 0 ; Reset Total
        $iTotalIndex = $i ; Remember index of lat parent type
    EndIf
Next
$aResult[$iTotalIndex][1] = $iTotalValue ; Insert last total of subtype values into parent type

_ArrayDisplay($aResult)
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

#include <Array.au3>


Global $aFirstArray[10][3] = [["Type1", "Subtype1", 10],["Type1", "Subtype2", 20], _
        ["Type1", "Subtype3", 30],["Type2", "Subtype4", 40], _
        ["Type2", "Subtype5", 50],["Type3", "Subtype5", 60], _
        ["Type4", "Subtype6", 70],["Type4", "Subtype7", 80], _
        ["Type5", "Subtype8", 90],["Type5", "Subtype9", 100]]


_ArrayDisplay($aFirstArray)



Global $aSecondArray[0][2]

$lasttype = ""
$sum = 0
$iType = -1

for $i = 0 to ubound($aFirstArray) - 1

    $type = $aFirstArray[$i][0]

    If $type = $lasttype then
        _ArrayAdd($aSecondArray , $aFirstArray[$i][1] & "|" & $aFirstArray[$i][2] , 0 , "|")
        $sum += $aFirstArray[$i][2]
    Else
        If $iType <> -1 Then $aSecondArray[$iType][1] = $sum
        $sum = 0
        $iType = _ArrayAdd($aSecondArray , $aFirstArray[$i][0])
        _ArrayAdd($aSecondArray , $aFirstArray[$i][1] & "|" & $aFirstArray[$i][2] , 0 , "|")
        $sum += $aFirstArray[$i][2]
    EndIf

    If $i = ubound($aFirstArray) - 1 Then $aSecondArray[$iType][1] = $sum

    $lasttype = $type

next


    _ArrayDisplay($aSecondArray, "To This")

1 person likes this

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

Share this post


Link to post
Share on other sites

Wow, pretty ace that bothouse, you're like an array wizard. I really appreciate you taking the time to help me out here.

What about if the input array has multiple values, like unknown amount of columns with values in.

Got any solutions for that?

#include <Array.au3>


Global $aFirstArray[10][4] = [["Type1", "Subtype1", 10, 1],["Type1", "Subtype2", 20, 2], _
        ["Type1", "Subtype3", 30, 3],["Type2", "Subtype4", 40, 4], _
        ["Type2", "Subtype5", 50, 5],["Type3", "Subtype5", 60, 6], _
        ["Type4", "Subtype6", 70, 7],["Type4", "Subtype7", 80, 8], _
        ["Type5", "Subtype8", 90, 9],["Type5", "Subtype9", 100, 10]]


_ArrayDisplay($aFirstArray)

Global $aSecondArray[0][2]

$lasttype = ""
$sum = 0
$iType = -1

for $i = 0 to ubound($aFirstArray) - 1

    $type = $aFirstArray[$i][0]

    If $type = $lasttype then
        _ArrayAdd($aSecondArray , $aFirstArray[$i][1] & "|" & $aFirstArray[$i][2] , 0 , "|")
        $sum += $aFirstArray[$i][2]
    Else
        If $iType <> -1 Then $aSecondArray[$iType][1] = $sum
        $sum = 0
        $iType = _ArrayAdd($aSecondArray , $aFirstArray[$i][0])
        _ArrayAdd($aSecondArray , $aFirstArray[$i][1] & "|" & $aFirstArray[$i][2] , 0 , "|")
        $sum += $aFirstArray[$i][2]
    EndIf

    If $i = ubound($aFirstArray) - 1 Then $aSecondArray[$iType][1] = $sum

    $lasttype = $type

next


    _ArrayDisplay($aSecondArray, "To This")

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

#10 ·  Posted (edited)

Wound up doing it like this.

#include <Array.au3>


Global $aFirstArray[10][5] = [["Type1", "Subtype1", 10, 1, 0.1],["Type1", "Subtype2", 20, 2, 0.2], _
        ["Type1", "Subtype3", 30, 3, 0.3],["Type2", "Subtype4", 40, 4, 0.4], _
        ["Type2", "Subtype5", 50, 5, 0.5],["Type3", "Subtype5", 60, 6, 0.6], _
        ["Type4", "Subtype6", 70, 7, 0.7],["Type4", "Subtype7", 80, 8, 0.8], _
        ["Type5", "Subtype8", 90, 9, 0.9],["Type5", "Subtype9", 100, 10, 0.0]]


_ArrayDisplay($aFirstArray, "First")

Local $iCols = UBound($aFirstArray, 2) - 1

Local $aResult[UBound($aFirstArray) * 2][$iCols], $sLast, $n = 0

For $x = 2 To $iCols
    $sLast = ""
    $n = 0
    For $i = 0 To UBound($aFirstArray) - 1

        If $aFirstArray[$i][0] <> $sLast Or $n = 0 Then

            $sLast = $aFirstArray[$i][0]
            $aResult[$n][0] = $sLast ; Add Type to array
            $n += 1
            $aResult[$n][0] = $aFirstArray[$i][1] ; Add Subtype to array
            $aResult[$n][$x - 1] = $aFirstArray[$i][$x] ; Add Value to array
        Else

            $aResult[$n][0] = $aFirstArray[$i][1] ; Add Subtype to array
            $aResult[$n][$x - 1] = $aFirstArray[$i][$x] ; Add Value to array
        EndIf
        $n += 1

    Next
Next
ReDim $aResult[$n][$iCols]

_ArrayDisplay($aResult, "Second")

; Adding The values of subtypes
$iTotalIndex = 0
$iTotalValue = 0
$iCols = UBound($aResult, 2) - 1

For $x = 1 To $iCols
    $iTotalIndex = 0
    $iTotalValue = 0
    For $i = 1 To UBound($aResult) - 1
        If $aResult[$i][$x] <> "" Then
            $iTotalValue += $aResult[$i][$x] ; Add value of Subtype
        Else
            $aResult[$iTotalIndex][$x] = $iTotalValue ; Insert total of subtype values into parent type
            $iTotalValue = 0 ; Reset Total
            $iTotalIndex = $i ; Remember index of lat parent type
        EndIf
    Next
    $aResult[$iTotalIndex][$x] = $iTotalValue ; Insert last total of subtype values into parent type
Next
_ArrayDisplay($aResult, "Third")

Thanks one again for your help boththose.

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

#11 ·  Posted (edited)

Well that works in the repo, but has a bug in my script proper :(

My script is too large with multiple includes to post up here, but if any long standing regular cares, and wouldn't mind looking at it, please let me know.

Cheers.

EDIT:See below

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

nice that is way cleaner than where mine was headed.  I think the _ArrayAdd solution may fall apart completely (or become quite unwieldy) with the requirement to handle an unknown number of columns.


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

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