JohnOne Posted March 16, 2015 Share Posted March 16, 2015 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 More sharing options...
Solution iamtheky Posted March 16, 2015 Solution Share Posted March 16, 2015 (edited) expandcollapse popup#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 March 16, 2015 by boththose JohnOne 1 ,-. .--. ________ .-. .-. ,---. ,-. .-. .-. .-. |(| / /\ \ |\ /| |__ __||| | | || .-' | |/ / \ \_/ )/ (_) / /__\ \ |(\ / | )| | | `-' | | `-. | | / __ \ (_) | | | __ | (_)\/ | (_) | | .-. | | .-' | | \ |__| ) ( | | | | |)| | \ / | | | | | |)| | `--. | |) \ | | `-' |_| (_) | |\/| | `-' /( (_)/( __.' |((_)-' /(_| '-' '-' (__) (__) (_) (__) Link to comment Share on other sites More sharing options...
Gianni Posted March 16, 2015 Share Posted March 16, 2015 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") JohnOne 1 Chimp small minds discuss people average minds discuss events great minds discuss ideas.... and use AutoIt.... Link to comment Share on other sites More sharing options...
jguinch Posted March 16, 2015 Share Posted March 16, 2015 (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 March 16, 2015 by jguinch JohnOne 1 Spoiler Network configuration UDF, _DirGetSizeByExtension, _UninstallList Firefox ConfigurationArray multi-dimensions, Printer Management UDF Link to comment Share on other sites More sharing options...
iamtheky Posted March 16, 2015 Share Posted March 16, 2015 (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 March 16, 2015 by boththose JohnOne 1 ,-. .--. ________ .-. .-. ,---. ,-. .-. .-. .-. |(| / /\ \ |\ /| |__ __||| | | || .-' | |/ / \ \_/ )/ (_) / /__\ \ |(\ / | )| | | `-' | | `-. | | / __ \ (_) | | | __ | (_)\/ | (_) | | .-. | | .-' | | \ |__| ) ( | | | | |)| | \ / | | | | | |)| | `--. | |) \ | | `-' |_| (_) | |\/| | `-' /( (_)/( __.' |((_)-' /(_| '-' '-' (__) (__) (_) (__) Link to comment Share on other sites More sharing options...
JohnOne Posted March 16, 2015 Author Share Posted March 16, 2015 Men, you're absolute sanity savers. Thank you very muchly. 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 More sharing options...
JohnOne Posted March 17, 2015 Author Share Posted March 17, 2015 (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? expandcollapse popup#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 March 17, 2015 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 More sharing options...
iamtheky Posted March 17, 2015 Share Posted March 17, 2015 expandcollapse popup#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") JohnOne 1 ,-. .--. ________ .-. .-. ,---. ,-. .-. .-. .-. |(| / /\ \ |\ /| |__ __||| | | || .-' | |/ / \ \_/ )/ (_) / /__\ \ |(\ / | )| | | `-' | | `-. | | / __ \ (_) | | | __ | (_)\/ | (_) | | .-. | | .-' | | \ |__| ) ( | | | | |)| | \ / | | | | | |)| | `--. | |) \ | | `-' |_| (_) | |\/| | `-' /( (_)/( __.' |((_)-' /(_| '-' '-' (__) (__) (_) (__) Link to comment Share on other sites More sharing options...
JohnOne Posted March 17, 2015 Author Share Posted March 17, 2015 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? expandcollapse popup#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 More sharing options...
JohnOne Posted March 17, 2015 Author Share Posted March 17, 2015 (edited) Wound up doing it like this. expandcollapse popup#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 March 17, 2015 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 More sharing options...
JohnOne Posted March 17, 2015 Author Share Posted March 17, 2015 (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 March 17, 2015 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 More sharing options...
JohnOne Posted March 17, 2015 Author Share Posted March 17, 2015 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 More sharing options...
iamtheky Posted March 17, 2015 Share Posted March 17, 2015 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 More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now