Jump to content

Parsing/converting array!


Go to solution Solved by iamtheky,

Recommended Posts

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.

Link to comment
Share on other sites

  • Solution

#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

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

Link to comment
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")

 

image.jpeg.9f1a974c98e9f77d824b358729b089b0.jpeg Chimp

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

Link to comment
Share on other sites

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
Link to comment
Share on other sites

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

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

Link to comment
Share on other sites

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.

Link to comment
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")

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

Link to comment
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.

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

Actually, I think I've fixed it.

Changing the line 

If $aResult[$i][$x] <> "" Then

To

If IsNumber($aResult[$i][$x]) Then

Because some of those elements were 0 and seemingly seen as "".

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

Monkey's are, like, natures humans.

Link to comment
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.

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

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