Jump to content

Yet another string 2d array thread


wysocki
 Share

Recommended Posts

After reading 97 threads about converting a string to a 2d array, I'm still having a problem. Probably something very simple that I'm blinded to. My input string has some unique qualities though.

I have a string that has rows separated by a  2char delimiter, and variable number of fields in each row separated by another. I load the rows into an array then loop through the rows, replacing each string of fields with an array of them. Appears to work ok by viewing with ArrayDisplay, but then I get an error when referring to an element with consolewrite. What am I doing wrong?

$data = 'a,b,c<>d,e,f,g<>h,i'
$lineArr = StringSplit($data, '<>',1)
for $i = 1 to $lineArr[0]
    $lineArr[$i] = stringsplit($lineArr[$i],',')
Next
_ArrayDisplay($lineArr) ;looks ok
_ArrayDisplay($lineArr[1]) ;looks ok
ConsoleWrite( $lineArr[1][1] & @CRLF) ;Error: Variable has incorrect number of subscripts

 

Link to comment
Share on other sites

  • Moderators

wysocki,

You need parentheses around the internal array - like this:

ConsoleWrite( ($lineArr[1])[1] & @CRLF)

What you were using makes AutoIt think you are trying to access a 2D array

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

Why not directly build a 2D array ?

#include <Array.au3>

$data = 'a,b,c<>d,e,f,g<>h,i'

Local $u2 = 1, $array[0][$u2]
$lineArr = StringSplit($data, '<>',1)
for $i = 1 to $lineArr[0]
   StringReplace($lineArr[$i], ",", ",")
   $tmp = @extended+1
   While $tmp > $u2
         _ArrayColInsert($array, $u2)
         $u2 += 1
   Wend
   _ArrayAdd($array, $lineArr[$i], 0, ",")
next
_ArrayDisplay($array)

 

Link to comment
Share on other sites

#include <Array.au3>
Local $b, $i, $m, $data = 'a,b,c<>d,e,f,g<>h,i'
Local $lineArr = StringSplit($data, '<>',1)
Local $a[UBound($lineArr)][1]
for $i = 1 to $lineArr[0]
    $b = stringsplit($lineArr[$i],',')
    If Not UBound($b) Then ContinueLoop
    If UBound($a,2) < $b[0] Then ReDim $a[UBound($a)][$b[0]]
    For $m = 1 To $b[0]
        $a[$i][$m - 1] = $b[$m]
    Next
Next
_ArrayDisplay($lineArr) ;looks ok
_ArrayDisplay($a) ;looks ok
ConsoleWrite( $a[1][1] & @CRLF)

Hope each line makes sense.

Follow the link to my code contribution ( and other things too ).
FAQ - Please Read Before Posting.
autoit_scripter_blue_userbar.png

Link to comment
Share on other sites

so nobody can find a fun way to just declare that string? I'll get you halfway, so you only have to figure out the hard part.

$data = 'a,b,c<>d,e,f,g<>h,i'

msgbox(0, '' , "[[" & stringreplace(stringreplace(StringRegExpReplace($data , "(\w)" , '"$1"') , ">" , "[") , "<" , "] , ") & "]]")

 

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

Link to comment
Share on other sites

Think I might have just found the stupidest bug ever, never seen inaccessible elements... 

#include<array.au3>

$data = 'a,b,c<>d,e,f,g<>h,i'

local $arr = [["[" & stringreplace(stringreplace(StringRegExpReplace($data , "(\w)" , '"$1"') , ">" , "[") , "<" , "] , ") & "]" ]]

_ArrayDisplay($arr)
msgbox(0, '' , $arr[0])

 

Edited by iamtheky

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

Link to comment
Share on other sites

1 hour ago, iamtheky said:

stupidest bug ever,

#include <array.au3>
$data = 'a,b,c<>d,e,f,g<>h,i'
Local $arr = [["[" & StringReplace(StringReplace(StringRegExpReplace($data, "(\w)", '"$1"'), ">", "["), "<", "] , ") & "]"]] ; <-- 2d array
_ArrayDisplay($arr, UBound($arr, 0) & " dimensions")
Switch UBound($arr, 0)
    Case 3
        MsgBox(0, UBound($arr, 0) & " dimensions", $arr[0][0][0])
    Case 2
        MsgBox(0, UBound($arr, 0) & " dimensions", $arr[0][0])
    Case 1
        MsgBox(0, UBound($arr, 0) & " dimensions", $arr[0])
EndSwitch

it's late, it happens :)

Edited by argumentum
clarify

Follow the link to my code contribution ( and other things too ).
FAQ - Please Read Before Posting.
autoit_scripter_blue_userbar.png

Link to comment
Share on other sites

1 hour ago, argumentum said:
....
Local $arr = [["[" & StringReplace(StringReplace(StringRegExpReplace($data, "(\w)", '"$1"'), ">", "["), "<", "] , ") & "]"]] ; <-- 2d array
....

 

If you have one leading and matching trailing square bracket the defined array is one dimensional.
If you have two leading and matching trailing square brackets the defined array is two dimensional.
If you have three leading and matching trailing square brackets the defined array is three dimensional.
All three different dimensional arrays would have the same first element.  That is the first element is all the text between the opening square bracket(s) and the closing square bracket(s) of the defined array.

 

And here is another string to 2D array example.

#include <Array.au3>

Local $data = 'a,b,c<>d,e,f,g<>h,i'
$a = _StringTo2DArray($data, ",", "<>")
_ArrayDisplay($a, $data)

Local $data = '[[a,b,c], [d,e,f,g], [h,i]]'
Local $data1 = StringTrimRight(StringTrimLeft($data, 2), 2) ; Remove first 2 square brackets, and last 2 square brackets.
$a = _StringTo2DArray($data1, ",", "], [")
_ArrayDisplay($a, $data)


Func _StringTo2DArray($sString, $sDelim_Columns = ",", $sDelim_Row = @CRLF)
    ; ---- Find number of columns ($iCols) to correctly dimension array ----
    Local $iCols = 0
    Local $sRE = "([^" & StringRegExpReplace($sDelim_Columns & $sDelim_Row, "([\[\]\-\^\\])", "\\$1") & "]+)"
    Local $lineArr = StringSplit(StringRegExpReplace($sString, $sRE, ""), $sDelim_Row, 1) ; 1 = entire delimiter string is needed to mark the split.
    ;_ArrayDisplay($lineArr)
    For $i = 1 To $lineArr[0]
        If (StringLen($lineArr[$i]) + 1) > $iCols Then $iCols = StringLen($lineArr[$i]) + 1
    Next
    ; ---- End of Find number of columns ----

    Local $aArray[0][$iCols]
    _ArrayAdd($aArray, $sString, 0, $sDelim_Columns, $sDelim_Row)
    Return $aArray
EndFunc   ;==>_StringTo2DArray

 

Link to comment
Share on other sites

ahhh, yes.  Brackets were abounding...

still though, can you declare that string?

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

Link to comment
Share on other sites

3 hours ago, iamtheky said:

can you declare that string?

IMHO, I would say... nope, because the brackets included in the string are considered as parts of this string and then loose their 'array delimiter' status
In this topic there are 3 different _StringTo2DArray things, and all contain loops to assign the array elements separately... how strange  :)

Link to comment
Share on other sites

so much fun, yall keep doing it one by one tho :)

$data = 'a,b,c<>d,e,f,g<>h,i'

FileDelete("testdeclare.au3")
filewrite("testdeclare.au3" , "#include<array.au3>" & @CRLF & "local $arr = [[" & stringreplace(stringreplace(StringRegExpReplace($data , "(\w+)" , '"$1"') , ">" , "[") , "<" , "] , ") & "]]" & @CRLF & "_ArrayDisplay($arr)")

runwait('C:\Program Files (x86)\AutoIt3\Aut2Exe\Aut2Exe.exe /in "testdeclare.au3" /out "testdeclare.exe"' , @ScriptDir)

run("testdeclare.exe")

 

Edited by iamtheky

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

Link to comment
Share on other sites

2 glaring issues I'm going after next 

1) requires that the column delimiter is a ","

2)  the items between the strings are all \w and no spaces or funny business. 

Here is a more user friendly copy to work from if you care to play, I'll replace this one as it gets friendlier.

$data = 'a,b,c<>d,e,f,g<>h,i'
;~ $data = 'a,bcd,ef<>ghij,klmn,o,pqrstuv<>wxy,z12,3'

$fIn = "in.au3"
$xOut = "out.exe"
$RowDelimeter = "<>"

If FileExists($fIn) Then FileDelete($fIn)
filewrite($fIn , "#include<array.au3>" & @CRLF & "local $arr = [[" & stringreplace(StringRegExpReplace($data , "(\w+)" , '"$1"') , $RowDelimeter , "],[") & "]]" & @CRLF & "_ArrayDisplay($arr)")
runwait('C:\Program Files (x86)\AutoIt3\Aut2Exe\Aut2Exe.exe /in ' & $fIn & ' /out ' & $xOut , @ScriptDir)
run($xOut)

 

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

Link to comment
Share on other sites

Glaring ? not so much...
1) If you know the row delimiter, aren't you supposed to know the column delimiter too ? if it is not a comma then stringreplace it
2) this one is only matter of pattern management  :)

$data = 'a,b,c<>d,e,f,g<>h,i<><>12.3-4,###,???,@^$'

$fIn = "in.au3"
$RowDelimeter = "<>"

If FileExists($fIn) Then FileDelete($fIn)
filewrite($fIn , "#include<array.au3>" & @CRLF & "local $arr = [[" & stringreplace(StringRegExpReplace($data , "([^,""]+)" , '"$1"') , $RowDelimeter , '"],["') & "]]" & @CRLF & "_ArrayDisplay($arr)")
ShellExecute($fIn)

butbutbut... THE issue is that this pretty nice array is still not available in the main script

Link to comment
Share on other sites

I was more just excited to declare the string, it’ll probably take another day to find an actual use case for it or someone smart to show us how to backhaul the return.

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

Link to comment
Share on other sites

_FileWriteFromArray() writes the correct number of columns (or commas) to each rows from an array to a file.

As an exercise this works, but the annoying thing is my Avast free antivirus checks, and passes this script each time it is run which takes about three seconds.

#include <Array.au3>
#include <File.au3>

;Local $Str = 'a,b,c<>d,e,f,g<>h,i'
Local $Str = '1st element,bcd,ef<>ghij,klmn,o,pqrstuv<>wxy,z12'
$aArray = _StringTo2DArray($Str, "<>")

MsgBox(0, "", "$aArray[0][0] contains " & $aArray[0][0])
_ArrayDisplay($aArray)


Func _StringTo2DArray($data, $RowDelimeter = @CRLF)
    Local $aArray, $fIn = "in.au3", $xOut = "out.exe", $TCSV = "TempCSV.csv"
    Local $sRE = "([^," & StringRegExpReplace($RowDelimeter, "([\[\]\-\^\\])", "\\$1") & "]+)"
    If FileExists($fIn) Then FileDelete($fIn)
    FileWrite($fIn, "#include <File.au3>" & @CRLF & _
            "local $arr = [[" & StringReplace(StringRegExpReplace($data, $sRE, '"$1"'), $RowDelimeter, "],[") & "]]" & @CRLF & _
            '_FileWriteFromArray("' & $TCSV & '", $arr, Default, Default, ",")')
    RunWait('C:\Program Files (x86)\AutoIt3\Aut2Exe\Aut2Exe.exe /in ' & $fIn & ' /out ' & $xOut, @ScriptDir)
    RunWait($xOut)
    _FileReadToArray($TCSV, $aArray, 0, ",")
    FileDelete($fIn)
    FileDelete($xOut)
    FileDelete($TCSV)
    Return $aArray
EndFunc   ;==>_StringTo2DArray

 

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