Jump to content

String to 2D array


Sodori
 Share

Recommended Posts

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?

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

Visit my repository

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

Link to comment
Share on other sites

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

 

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

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

Visit my repository

Link to comment
Share on other sites

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

Edited by Danyfirex
Link to comment
Share on other sites

@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

 

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

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

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

 

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

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

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

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

Link to comment
Share on other sites

@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

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

:)

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

Link to comment
Share on other sites

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