Sign in to follow this  
Followers 0
Sodori

String to 2D array

24 posts in this topic

Hi,

Been searching all over for quite a while now, but cannot find anything about it! From clipboard, I get a string containing line feeds and tabs. I want to make it into a multi dimensional array. Something like this:

 

4010506 1341001 4019001 4010014 2425012 4010030

1 5 4 3 8 7
1 5 4 3 8 7
1 5 4 3 8 7

 

Granted this forum does not support tabs, so it's a white space instead. so white spaces = next column and linefeed = next row. How do I convert such string to an array?

Share this post


Link to post
Share on other sites



maybe this?

#include <Array.au3>

Local $str = "4010506 1341001 4019001 4010014 2425012 4010030" & @LF & _
        "1 5 4 3 8 7" & @LF & _
        "1 5 4 3 8 7" & @LF & _
        "1 5 4 3 8 7"



Local $arr = BuildArray($str, 6)
_ArrayDisplay($arr)

Func BuildArray($str = "", $cols = 6)
    $str = StringReplace($str, @CRLF, "|")
    $str = StringReplace($str, @CR, "|")
    $str = StringReplace($str, @LF, "|")
    $str = StringSplit($str, "|", 2)
    Local $arr[1][$cols]
    Local $cell
    For $ii = 0 To UBound($str, 1) - 1
        $cell = StringSplit($str[$ii], " ", 2)
        ReDim $arr[UBound($arr, 1) + 1][$cols]
        For $jj = 0 To UBound($cell, 1) - 1
            $arr[$ii][$jj] = $cell[$jj]
        Next
    Next
    _ArrayDelete($arr, UBound($arr, 1) - 1)
    Return $arr
EndFunc   ;==>BuildArray

m(o.O)m

Share this post


Link to post
Share on other sites

or this:

#include <Array.au3>

Local $str = "4010506 1341001 4019001 4010014 2425012 4010030" & @LF & _
        "1 5 4 3 8 7" & @LF & _
        "1 5 4 3 8 7" & @LF & _
        "1 5 4 3 8 7"


Local $aArray=StringSplit($str ," " & @CRLF)
Local $iFilas=StringSplit($str,@CRLF)
Local $iCol=StringSplit($iFilas[1]," ")[0]
$iFilas=$iFilas[0]
Local $aArray2D[$iFilas][$iCol]
Local $i=0
For $f= 0 to $iFilas-1
    For $c=0 to $iCol-1
        $aArray2D[$f][$c]=$aArray[$i+$c+1]
    Next
    $i+=$iCol
Next


_ArrayDisplay($aArray2D)

Saludos

1 person likes this

 

venezuela.png Would you like to say thank to Danyfirex using a warmy way?  offer me a cup of coffee... coffee.png

autoit_scripter_blue_userbar.png

       AutoIt...

 

 

Share this post


Link to post
Share on other sites

#4 ·  Posted (edited)

or even this

(copy your data to the clipboard before run this listing)

#include <array.au3> ; just to show result

Local $aArray1 = StringSplit(StringStripCR(ClipGet()), @LF), $aArray2, $aResult[$aArray1[0]][1]
For $i = 1 To $aArray1[0]
    $aArray2 = StringSplit($aArray1[$i], @TAB)
    If  $aArray2[0] > UBound($aResult, 2) Then ReDim $aResult[$aArray1[0]][$aArray2[0]]
        For $i2 = 1 To $aArray2[0]
            $aResult[$i-1][$i2-1] = $aArray2[$i2]
        Next
Next

_ArrayDisplay($aResult)

edit:

skin as Function

#include <array.au3> ; just to show result
;
$sMyVar = ClipGet() ; from Clipboard to a variable
_ArrayDisplay(_VarTo2D($sMyVar))
;
Func _VarTo2D($var, $sSeparator = @TAB)
    Local $aRows = StringSplit(StringStripCR($var), @LF), $aColumns, $aResult[$aRows[0]][1]
    For $iRow = 1 To $aRows[0]
        $aColumns = StringSplit($aRows[$iRow], $sSeparator)
        If $aColumns[0] > UBound($aResult, 2) Then ReDim $aResult[$aRows[0]][$aColumns[0]]
        For $iColumn = 1 To $aColumns[0]
            $aResult[$iRow - 1][$iColumn - 1] = $aColumns[$iColumn]
        Next
    Next
    Return $aResult
EndFunc   ;==>_VarTo2D
Edited by Chimp
2 people like 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

Or this...

#include <Array.au3>

Local $str = "4010506 1341001 4019001 4010014 2425012 4010030" & @LF & _
        "1 5 4 3 8 7" & @LF & _
        "1 5 4 3 8 7" & @LF & _
        "1 5 4 3 8 7"

Local $arr[1][6]
BuildArray($arr, $str)
_ArrayDisplay($arr)

Func BuildArray(ByRef $arr, $str = "")
    $str = StringReplace($str, @CR, "|")
    $str = StringReplace($str, @LF, "|")
    $str = StringReplace($str, @CRLF, "|")
    _ArrayAdd($arr, $str, 0, " ", "|", Number)
    _ArrayDelete($arr, 0)
EndFunc   ;==>BuildArray

m(o.O)m

Share this post


Link to post
Share on other sites

sorry Danyfirex and Detefon, but your ways suppose that the input data has the same number of columns for each row.


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

#7 ·  Posted (edited)

@chimp mine is dynamic. and yours is not 2D.

Edited by Danyfirex

 

venezuela.png Would you like to say thank to Danyfirex using a warmy way?  offer me a cup of coffee... coffee.png

autoit_scripter_blue_userbar.png

       AutoIt...

 

 

Share this post


Link to post
Share on other sites

#8 ·  Posted (edited)

@chimp mine is dynamic. and yours is not 2D.

 

try to get this data:

Local $str = "4010506" & @LF & _
        "1 5 4 3 8 7" & @LF & _
        "1 5 4 3 8 7" & @LF & _
        "1 5 4 3 8 7"

edit:

.....  and yours is not 2D.

 

?? it is instead

... I split columns by @tab and not by spaces, as OP ask

Edited by Chimp

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

mmm I see.


 

venezuela.png Would you like to say thank to Danyfirex using a warmy way?  offer me a cup of coffee... coffee.png

autoit_scripter_blue_userbar.png

       AutoIt...

 

 

Share this post


Link to post
Share on other sites

#10 ·  Posted (edited)

Sodori,

Splits EOL delimited string with user specified column delimiters.  Each row can have any number of columns... 

< code removed >

kylomas

Edited by kylomas

Forum Rules         Procedure for posting code

"I like pigs.  Dogs look up to us.  Cats look down on us.  Pigs treat us as equals."

- Sir Winston Churchill

Share this post


Link to post
Share on other sites

Sodori,

Splits EOL delimited string with user specified column delimiters.  Each row can have any number of columns... 

kylomas

 

it returns an extra column


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

#12 ·  Posted (edited)

Fixed...

#include <array.au3>

; EOL delimited string with tab delimited columns
;~ local $str = '4010506   1341001 4019001 4010014 2425012 4010030' & @lf & _
;~             '1  5   4   3   8   7   10  12'                      & @crlf & _
;~             '1  5   4   3'                                       & @lf & _
;~             '1  5   4   3   8   7'

local $str = fileread(@scriptdir & '\string_split_test.txt')

_arraydisplay(_DBG_StringSplit2D($str, @tab),'String Converted to 2D Array')

func _DBG_StringSplit2d(byref $str,$delimiter)

    ; #FUNCTION# ======================================================================================
    ; Name ................:    _DBG_StringSplit2D($str,$delimiter)
    ; Description .........:    Create 2d array from delimited string
    ; Syntax ..............:    _DBG_StringSplit2D($str, $delimiter)
    ; Parameters ..........:    $str        - EOL (@CR, @LF or @CRLF) delimited string to split
    ;                           $delimiter  - Delimter for columns
    ; Return values .......:    2D array
    ; Author ..............:    kylomas
    ; =================================================================================================

    local $a1 = stringregexp($str,'.*?(?:\R|$)',3), $a2

    local $rows = ubound($a1) - 1, $cols = 0

    ; determine max number of columns by splitting each row and keeping highest ubound value

    for $i = 0 to ubound($a1) - 1
        $a2 = stringsplit($a1[$i],$delimiter,1)
        if ubound($a2) > $cols then $cols = ubound($a2)
    next

    ; define and populate array

    local $aRET[$rows][$cols-1]

    for $i = 0 to $rows - 1
        $a2 = stringsplit($a1[$i],$delimiter,3)
        for $j = 0 to ubound($a2) - 1
            $aRET[$i][$j] = $a2[$j]
        Next
    next

    return $aRET

endfunc
Edited by kylomas
1 person likes this

Forum Rules         Procedure for posting code

"I like pigs.  Dogs look up to us.  Cats look down on us.  Pigs treat us as equals."

- Sir Winston Churchill

Share this post


Link to post
Share on other sites

Really nice and helpful. Thank you all! Kylomas, yours looks like it just as well could have been extracted from the included library or something, well done! If I were to plop this in a separate .au3 and have it in included library. I'd choose yours. However, I think I like chimps for my situation of simply copy paste function into code. However my used function list is starting to grow to the point where I probably should just use like first mentioned xD Bravo!

Share this post


Link to post
Share on other sites

kylomas,

To get your code to work nicely (using the sample string, not the FileRead) I had to add parenthesis to make a capturing group, otherwise EOL are grabbed too

local $a1 = stringregexp($str,'(.*?)(?:\R|$)', 3)

Share this post


Link to post
Share on other sites

#15 ·  Posted (edited)

@mikell - Thanks, was goofing around with that last night.  Finally just deleted the last member of the array (poor solution)...

Question : Why was the last EOL captured?  I thought the non-capturing group would take care of that...

kylomas

edit:

@Sordori - The best solution is usually the simplest that will solve the problem.

Edited by kylomas

Forum Rules         Procedure for posting code

"I like pigs.  Dogs look up to us.  Cats look down on us.  Pigs treat us as equals."

- Sir Winston Churchill

Share this post


Link to post
Share on other sites

I don't know and couldn't find an explanation in the reference documentation

It's a matter of internal sre engine, maybe jchd can answer ...

#Include <Array.au3>
$str = "foobar"
$res1 = StringRegExp($str, '\w+(?:bar)', 3)
 _ArrayDisplay($res1)
$res2 = StringRegExp($str, '(\w+)(?:bar)', 3)
 _ArrayDisplay($res2)

Anyway for your func my personal choice would be

local $a1 = StringRegExp($str, '[^\r\n]+', 3)

:)

Share this post


Link to post
Share on other sites

@mikell - Thanks...


Forum Rules         Procedure for posting code

"I like pigs.  Dogs look up to us.  Cats look down on us.  Pigs treat us as equals."

- Sir Winston Churchill

Share this post


Link to post
Share on other sites

@mikell - I tried that but it did not work.  This is the current code...

#include <array.au3>

Local $gendata = True
Local $row = 5 ;    # of rows to generate
Local $maxcol = 10 ;   max number of cols to generate

If $gendata Then _gendata($row, $maxcol)

Local $aRET = _DBG_StringSplit2d(FileRead(@ScriptDir & '\test.txt'), @TAB, 1)

_ArrayDisplay($aRET)

Func _DBG_StringSplit2d($str, $delimiter, $showtiming = 0)

    ; #FUNCTION# ======================================================================================
    ; Name ................:    _DBG_StringSplit2D($str,$delimiter)
    ; Description .........:    Create 2d array from delimited string
    ; Syntax ..............:    _DBG_StringSplit2D($str, $delimiter)
    ; Parameters ..........:    $str        - EOL (@CR, @LF or @CRLF) delimited string to split
    ;                           $delimiter  - Delimter for columns
    ;                           $showtiming - Display time to create 2D array to the console
    ; Return values .......:    2D array
    ; Author ..............:    kylomas
    ; =================================================================================================

    If $showtiming Then $st = TimerInit()

    Local $a1 = StringRegExp($str, '(.*?)(?:\R|$)', 3)

    ;ReDim $a1[UBound($a1) - 1]

    Local $rows = UBound($a1), $cols = 0

    ; determine max number of columns
    For $i = 0 To UBound($a1) - 1
        StringReplace($a1[$i], $delimiter, '')
        $cols = (@extended > $cols ? @extended : $cols)
    Next

    ; define and populate array
    Local $aRET[$rows][$cols + 1]

    For $i = 0 To UBound($a1) - 1
        $a2 = StringSplit($a1[$i], $delimiter, 3)
        For $j = 0 To UBound($a2) - 1
            $aRET[$i][$j] = $a2[$j]
        Next
    Next

    If $showtiming Then ConsoleWrite('!-----------' & _
            @LF & 'Time to format ' & UBound($aRET) * ($cols + 1) & ' (' & UBound($aRET) & ' X ' & $cols + 1 & ') cell 2D array = ' & _
            StringFormat('%4.2f', TimerDiff($st) / 1000) & ' seconds.' & @LF & _
            '!------------' & @LF)

    Return $aRET

EndFunc   ;==>_DBG_StringSplit2d

Func _gendata($r, $c)

    ; ------------------ generate test data ---------------------------
    ConsoleWrite(StringFormat('%-40s %02s:%02s:%02s', 'Start test data generation', @HOUR, @MIN, @SEC) & @CRLF)
    Local $str
    FileDelete(@ScriptDir & '\test.txt')
    For $1 = 1 To $r
        For $2 = 1 To Random(1, $c, 1)
            $str &= StringFormat('%05i', Random(1, 10000, 1)) & @TAB
        Next
        $str = StringTrimRight($str, 1)
        $str &= @CRLF
    Next
    FileWrite(@ScriptDir & '\test.txt', $str)
    ConsoleWrite(StringFormat('%-40s %02s:%02s:%02s', 'End test data generation', @HOUR, @MIN, @SEC) & @CRLF)

EndFunc   ;==>_gendata

Forum Rules         Procedure for posting code

"I like pigs.  Dogs look up to us.  Cats look down on us.  Pigs treat us as equals."

- Sir Winston Churchill

Share this post


Link to post
Share on other sites

@mikell - I changed to your pattern and the blank entry at the end goes away.  Don't get why????


Forum Rules         Procedure for posting code

"I like pigs.  Dogs look up to us.  Cats look down on us.  Pigs treat us as equals."

- Sir Winston Churchill

Share this post


Link to post
Share on other sites

#20 ·  Posted (edited)

For the text you generate, my Metapad says "6 lines"

If I add this before the FileWrite : $str = StringStripWS($str, 2) then it says "5 lines" , but in the array the blank line at the end still remains

But if the regex is done like this

Local $a1 = StringRegExp($str, '(.+?)(?:\R|$)', 3)

in both cases all is ok  :)

Edited by mikell

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