-1

I try to split a string into a multidimensional array, but it is not working the way I want. I just split a string to some arrays where one 2 dimensional array should represent a table. I can see the array using _ArrayDisplay() but I cannot work with the array elements itself. The Line:

For $j = 1 To $aTable1Row[$i][0]

reports "incorrect number of subscripts". But if I do:

MsgBox(1, "TEST", UBound($aTable1Row[$i]))

it shows this array has 8 elements. So they are there but I somehow cannot access them. Full source code:

#include <Array.au3>

$string = "az#1:y#2:x#3:w#4:v#5:u#6:t#7-bz#1:y#2:x#3:w#4:v#5:u#6:t#7-cz#1:y#2:x#3:w#4:v#5:u#6:t#7"

$aTable1 = StringSplit($string, '-',1)
_ArrayDisplay($aTable1)
;3
;az#1:y#2:x#3:w#4:v#5:u#6:t#7
;bz#1:y#2:x#3:w#4:v#5:u#6:t#7
;cz#1:y#2:x#3:w#4:v#5:u#6:t#7

Local $aTable1Row[$aTable1[0]+1]
$aTable1Row[0] = $aTable1[0]    

For $i = 1 To $aTable1Row[0]
    $aTable1Row[$i] = StringSplit($aTable1[$i], ':',1)
    _ArrayDisplay($aTable1Row[$i])
    ;7
    ;az#1
    ;y#2
    ;x#3
    ;w#4
    ;v#5
    ;u#6
    ;t#7

    ;do stuff
    For $j = 1 To $aTable1Row[$i][0]
        $aTable1Row[$i][$j] = StringTrimLeft(($aTable1Row[$i])[$j], StringInStr(($aTable1Row[$i])[$j], '#'))
    Next
Next
user4157124
  • 2,809
  • 13
  • 27
  • 42
Hunselfunsel
  • 329
  • 1
  • 3
  • 15

2 Answers2

0

… this array has 8 elements.

That For -loop addresses a 1 dimensional array as if it were a 2 dimensional one, hence the Array variable has incorrect number of subscripts or subscript dimension range exceeded. -error.

Declare a 2 dimensional array first. Example (no error-checking):

#include <StringConstants.au3>
#include <Array.au3>

Global Const $g_sString   = 'az#1:y#2:x#3:w#4:v#5:u#6:t#7-bz#1:y#2:x#3:w#4:v#5:u#6:t#7-cz#1:y#2:x#3:w#4:v#5:u#6:t#7'
Global Const $g_sDelimRow = '-'
Global Const $g_sDelimCol = ':'
Global Const $g_aArray2D  = StringSplitToArray2D($g_sString, $g_sDelimRow, $g_sDelimCol)

_ArrayDisplay($g_aArray2D, @ScriptName)

Func StringSplitToArray2D(Const $sString, Const $sDelimiterRow, Const $sDelimiterCol)
    Local $aArray1DRows = StringSplit($sString,         $sDelimiterRow, $STR_ENTIRESPLIT)
    Local $aArray1DCols = StringSplit($aArray1DRows[1], $sDelimiterCol, $STR_ENTIRESPLIT)
    Local $aArray2D[ $aArray1DRows[0] + 1 ][ $aArray1DCols[0] + 1 ]

    For $i1 = 1 To $aArray1DRows[0]

        $aArray1DCols = StringSplit($aArray1DRows[$i1], $sDelimiterCol, $STR_ENTIRESPLIT)

        For $i2 = 1 To $aArray1DCols[0]

            $aArray2D[$i1][$i2] = $aArray1DCols[$i2]

        Next

    Next

    Return $aArray2D
EndFunc

Consider _FileReadToArray() if stored as text/CSV file. Related.

user4157124
  • 2,809
  • 13
  • 27
  • 42
0
#include <StringConstants.au3>
#include <Array.au3>

Global Const $g_sString   = 'az#1:y#2:x#3:w#4:v#5:u#6:t#7-bz#1:y#2:x#3:w#4:v#5:u#6:t#7-cz#1:y#2:x#3:w#4:v#5:u#6:t#7'
Global Const $g_sDelimRow = '-'
Global Const $g_sDelimCol = ':'
Global Const $g_aArray2D  = StringSplit2D($g_sString, $g_sDelimCol, $g_sDelimRow)

_ArrayDisplay($g_aArray2D, @ScriptName)

Func StringSplit2D($sMatches = "Hola-2-5-50-50-100-100|Hola-6-200-200-100-100", Const $sDelim_Item = "-", Const $sDelim_Row = "|")
    Local $iValDim_1, $iValDim_2 = 0, $iColCount
    Local $aSplit_1 = StringSplit($sMatches, $sDelim_Row, $STR_NOCOUNT + $STR_ENTIRESPLIT)
    $iValDim_1 = UBound($aSplit_1, $UBOUND_ROWS)
    Local $aTmp[$iValDim_1][0], $aSplit_2
    For $i = 0 To $iValDim_1 - 1
        $aSplit_2 = StringSplit($aSplit_1[$i], $sDelim_Item, $STR_NOCOUNT + $STR_ENTIRESPLIT)
        $iColCount = UBound($aSplit_2)
        If $iColCount > $iValDim_2 Then
            $iValDim_2 = $iColCount
            ReDim $aTmp[$iValDim_1][$iValDim_2]
        EndIf
        For $j = 0 To $iColCount - 1
            $aTmp[$i][$j] = $aSplit_2[$j]
        Next
    Next
    Return $aTmp
EndFunc   ;==>StringSplit2D

It is a very stable function and it was used in massive projects, tested millions of times.

Result

boludoz
  • 36
  • 4