Sign in to follow this  
Followers 0
johnmcloud

Add entry to 2D array

16 posts in this topic

Hi

I have ask some time ago a similar question but i think i have used a wrong method.

My idea was adding a pipe between word, then split the | and every single char. But is better to post directly the script

#include <Array.au3>

Global $aString

Add2DEntry("ABC[123CDE]")
Add2DEntry("ABCD[DEF]")
Add2DEntry("ABCD[H1]EFG")
Add2DEntry("ABC")

_ArrayDisplay($aString)

Func Add2DEntry($sAdd2DEntry)
    If Not IsDeclared("$sString") Then Global $sString
    If StringRight($sAdd2DEntry, 1) <> "|" Then $sAdd2DEntry = $sAdd2DEntry & "|"
    $sString &= $sAdd2DEntry
    Local $aSplit_1 = StringSplit(StringTrimRight($sString, 1), "|", 1)
    Global $aString[1][$aSplit_1[0]], $iNum = 0
    For $i = 1 To $aSplit_1[0]
        $sLine = $aSplit_1[$i]
        $iLen = StringLen($sLine)
        Local $aSplit_2[$iLen + 1]
        $iWriteindex = 0
        For $iReadIndex = 1 To $iLen
            $sChar = StringMid($sLine, $iReadIndex, 1)
            $aSplit_2[$iWriteindex] = $sChar
            If $sChar = "[" Then
                Do
                    $iReadIndex += 1
                    $sChar = StringMid($sLine, $iReadIndex, 1)
                    $aSplit_2[$iWriteindex] &= $sChar
                Until $sChar = "]"
            EndIf
            ConsoleWrite($aSplit_2[$iWriteindex] & @CR) ; <<<<<<<<<<<<<<< so many re-declare!
            $iWriteindex += 1
        Next
        If UBound($aString) < $iWriteindex Then
            ReDim $aString[$iWriteindex][$aSplit_1[0]]
        EndIf
        For $j = 0 To $iWriteindex - 1
            $aString[$j][$i - 1] = $aSplit_2[$j]
        Next
    Next
EndFunc   ;==>Add2DEntry

The result of _ArrayDisplay is correct but i see in the ConsoleWrite the Function is not very "clean", for my mistake. So is possible to "improve" the function and having the same result of _ArrayDisplay?

Thanks again

Share this post


Link to post
Share on other sites



This example adds the array from the regular expression to the 2D array.

#include <Array.au3>

Global $aArray2D[0][0]

Add2DEntry($aArray2D, "ABC[123CDE]")
Add2DEntry($aArray2D, "[AB]CD[][E][FG]H")
Add2DEntry($aArray2D, "ABCD[H1]EFG")
Add2DEntry($aArray2D, "ABC")

_ArrayDisplay($aArray2D)


Func Add2DEntry(ByRef $aArray, $sAdd2DEntry)
    Local $iMaxRows = UBound($aArray)
    $Col = UBound($aArray, 2) + 1 ; Increment number of columns
    Local $aTemp = StringRegExp($sAdd2DEntry, "(\[.*?\]|.)", 3)
    If UBound($aTemp) > $iMaxRows Then $iMaxRows = UBound($aTemp)
    ReDim $aArray[$iMaxRows][$Col]
    For $Row = 0 To UBound($aTemp) - 1
        $aArray[$Row][$Col - 1] = $aTemp[$Row]
    Next
EndFunc   ;==>Add2DEntry

Share this post


Link to post
Share on other sites

#3 ·  Posted (edited)

Malkey,

First thanks for your help. I have a couple of problem because your code is a bit different ( and short ) respect of the one of the first post ;)

In first place i can't declare empty array, i'm using the old stable and for now is complicated to update to last stable:

Global $aArray2D[0][0]

I have resolved this part declaring an 1D array, will be converted in 2D inside the _Add2DEntry and the ReDim part

Global $aArray2D[1]

The second one and most important, you use RegEx for the string inside the [ ] insted of looping like mine with Do...Until ( If $sChar = "[" Then Do...Until $sChar = "]" )

So i have another "rules" to apply...i have a character set:

£$?&

If one or more of that charset is followed by a char ( only the first one ) take it to a single row like the [ ]

Example:

ABC[123CDE]$a --> take $a to a single row

ABC$?1EFG[123CDE] --> take $?1 to single row

and so on.

If one of more of that charset is not followed by a char ( like at the end of the string ) remove it/skip it

Example:

ABC[123CDE]$ --> result is ABC[123CDE]

If is followed by [ put everything on a single row:

ABC&?[123CDE] ---> result is &?[123CDE]

Thanks. I'm sorry for not put this part on the first post but I did not think your code would have been different from that ;)

P.S. [ ] without any char inside it is an invalid entry so i can't add it to the final array, i'm using StringReplace on $sAdd2DEntry for that. I don't know if is possible to remove it if no char between/extract the char between [...] using only one RegExp without make 2 different pass. If not isn't a problem, i'll use StringReplace.

Edited by johnmcloud

Share this post


Link to post
Share on other sites

#4 ·  Posted (edited)

Malkey,

I have make the regexp for the things i have say in the previus post:

StringRegExp($sAdd2DEntry, "([£$?&]+(?:\[.*?\]|[^\s£$?&]))", 3)

Hope is correct. If you can make one fuction for everything i'm grateful. Have a nice day

Edited by johnmcloud

Share this post


Link to post
Share on other sites

#5 ·  Posted (edited)

Here's hoping this example will work on an older version of AutoIt.

The Static variable declaration has been around for for a while.   We will see.

#include <Array.au3>

Global $aArray2D

Add2DEntry($aArray2D, "ABC[123CDE]")
Add2DEntry($aArray2D, "[AB]CD[][E][FG]H")
Add2DEntry($aArray2D, "ABCD[H1]EFG")
Add2DEntry($aArray2D, "ABC")
Add2DEntry($aArray2D, "ABC[123CDE]$a")
Add2DEntry($aArray2D, "ABC$?1EFG[123CDE]")
Add2DEntry($aArray2D, "ABC[123CDE]$")
Add2DEntry($aArray2D, "ABC&?[123CDE]")

_ArrayDisplay($aArray2D)


Func Add2DEntry(ByRef $aArray, $sAdd2DEntry)
    Local Static $Col
    Local $iMaxRows = UBound($aArray)
    $Col += 1 ; Increment number of columns
    $sAdd2DEntry = StringRegExpReplace($sAdd2DEntry, "([£\$?&]+)(\[|$)", "\2") ; Remove unwanted characters - £$?& followed by [ or end of string.
    Local $aTemp = StringRegExp($sAdd2DEntry, "(\[.*?\]|[£\$?&]+.|.)", 3)
    If UBound($aTemp) > $iMaxRows Then $iMaxRows = UBound($aTemp)
    If $Col = 1 Then
        $aArray = $aTemp
    ElseIf $Col = 2 Then ; 1D to 2D array
        Local $aTemp2 = $aArray ; Changing dimensions with ReDim erases contents of array.
        ReDim $aArray[$iMaxRows][2]
        For $Row = 0 To $iMaxRows - 1
            If $Row < UBound($aTemp2) Then $aArray[$Row][0] = $aTemp2[$Row]
            If $Row < UBound($aTemp) Then $aArray[$Row][1] = $aTemp[$Row]
        Next
    Else
        ReDim $aArray[$iMaxRows][$Col]
        For $Row = 0 To $iMaxRows - 1
            If $Row < UBound($aTemp) Then $aArray[$Row][$Col - 1] = $aTemp[$Row]
        Next
    EndIf
EndFunc   ;==>Add2DEntry
Edited by Malkey

Share this post


Link to post
Share on other sites

#6 ·  Posted (edited)

Work but also the previus one work with some changes, from your last script:

#include <Array.au3>

Global $aArray2D[1] ; <<<<<<<<<<<<<<<<<<<<<< 1D

Add2DEntry($aArray2D, "ABC[123CDE]")
Add2DEntry($aArray2D, "[AB]CD[][E][FG]H")
Add2DEntry($aArray2D, "ABCD[H1]EFG")
Add2DEntry($aArray2D, "ABC")
Add2DEntry($aArray2D, "ABC[123CDE]$a")
Add2DEntry($aArray2D, "ABC$?1EFG[123CDE]")
Add2DEntry($aArray2D, "ABC[123CDE]$")
Add2DEntry($aArray2D, "ABC&?[123CDE]")

_ArrayDisplay($aArray2D)


Func Add2DEntry(ByRef $aArray, $sAdd2DEntry)
;~  Local Static $Col
    Local $iMaxRows = UBound($aArray)
    $Col = UBound($aArray, 2) + 1 ; <<<<<<<<<<<<<<<<< Increment number of columns
    $sAdd2DEntry = StringRegExpReplace($sAdd2DEntry, "([£\$?&]+)(\[|$)", "\2") ; Remove unwanted characters - £$?& followed by [ or end of string.
    Local $aTemp = StringRegExp($sAdd2DEntry, "(\[.*?\]|[£\$?&]+.|.)", 3)
    If UBound($aTemp) > $iMaxRows Then $iMaxRows = UBound($aTemp)
;~     If $Col = 1 Then
;~         $aArray = $aTemp
;~     ElseIf $Col = 2 Then ; 1D to 2D array
;~         Local $aTemp2 = $aArray ; Changing dimensions with ReDim erases contents of array.
;~         ReDim $aArray[$iMaxRows][2]
;~         For $Row = 0 To $iMaxRows - 1
;~             If $Row < UBound($aTemp2) Then $aArray[$Row][0] = $aTemp2[$Row]
;~             If $Row < UBound($aTemp) Then $aArray[$Row][1] = $aTemp[$Row]
;~         Next
;~     Else
        ReDim $aArray[$iMaxRows][$Col]
        For $Row = 0 To $iMaxRows - 1
            If $Row < UBound($aTemp) Then $aArray[$Row][$Col - 1] = $aTemp[$Row]
        Next
;~     EndIf
EndFunc   ;==>Add2DEntry

I have commented "unecessary" code and change the first array variable and $Col. I think the result is the same ;)

With the last script there is a problem with this entry:

Add2DEntry($aArray2D, "ABC[123CDE]")
Add2DEntry($aArray2D, "ABC&?[123CDE]")

Both give me the same result but are different ( see my regexp )

The first is:

A

B

C

[123CDE]

The second need to be:

A

B

C

&?[123CDE]

From my post:

If one of more of that charset is not followed by a char ( like at the end of the string ) remove it/skip it

Example:

ABC[123CDE]$ --> result is ABC[123CDE]

If is followed by [ put everything on a single row:

ABC&?[123CDE] ---> result is &?[123CDE]

Thanks ;)

Edited by johnmcloud

Share this post


Link to post
Share on other sites

This line removes all "unwanted" characters:

StringRegExpReplace($sAdd2DEntry, "([£\$?&]+)(\[|$)", "\2")

Are you saying they are NOT unwanted characters?


[center]Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.[/center]

Share this post


Link to post
Share on other sites

#8 ·  Posted (edited)

They are "wanted" character if:

a ) Is followed by a char, so take only the fist one match, so return $a or $?1 ( Done )

b ) Is followed by a [ so take the entire match, like $[ABC]

They are "unwanted" char if:

c ) They are not followed by a char, like at the end of the string [ABC]% ( Done )

That regexp only remove the unwanted char but i need something also for point b ) maybe can be done in the same regexp that split the character between square --> "([.*?]|[£$?&]+.|.)"

Edited by johnmcloud

Share this post


Link to post
Share on other sites

You're getting closer to be descriptive.  But a "char" is any character (decimal 0 - 255 for just the Ascii table alone).

You have all these rules, but it's difficult to follow (I'm only guessing english is not your native tongue).

Provide a list of all scenarios, then provide the output you'd expect from them.


[center]Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.[/center]

Share this post


Link to post
Share on other sites

#10 ·  Posted (edited)

The last script posted by Malkey follow all the rules except the one i have descripted at point b )

Add2DEntry($aArray2D, "ABC&?[123CDE]")

Expecetd result is:

A

B

C

&?[123CDE]

Actually is:

A

B

C

[123CDE]

The charset is always the same ( £$?& ) can be one of more of that previus the [ 

All the rest is already covered by the two regexp. Yes english is not my mother languages, i'll try to make the best :D

Edited by johnmcloud

Share this post


Link to post
Share on other sites

Again...

StringRegExpReplace($sAdd2DEntry, "([£$?&]+)([|$)", "2")

Makes it impossible to get your request.  It replaces all those special characters before the square bracket.  Try removing that line of code entirely.


[center]Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.[/center]

Share this post


Link to post
Share on other sites

#12 ·  Posted (edited)

I don't need to "replaces all those special characters before the square bracket" but only if the "special characters" is not followed by a char, like at the end of the string. Example:

ABC[123CDE]&? become ABC[123CDE]

If i remove the line the result is:

A

B

C

&?[

1

2

3

C

D

E

]

Edited by johnmcloud

Share this post


Link to post
Share on other sites

So...

$sAdd2DEntry = StringRegExpReplace($sAdd2DEntry, "([£\$?&]+$)", "") ; remove unwanted characters only at the end of the string.
Local $aTemp = StringRegExp($sAdd2DEntry, "([£\$?&]*\[.*?\]|.)", 3)

[center]Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.[/center]

Share this post


Link to post
Share on other sites

#14 ·  Posted (edited)

Your version work for point b ) but break the point a ) ( that was included in regexp of Malkey, try it out ) from post #8 :(

Add2DEntry($aArray2D, "ABC[123CDE]$a")

Expected result:

A

B

C

[CDE]

$a

Actual result:

A

B

C

[CDE]

$

a

Add2DEntry($aArray2D, "ABC?$1EFG[123CDE]")

Expected result:

A

B

C

?$1

E

F

G

[123CDE]

Edited by johnmcloud

Share this post


Link to post
Share on other sites

So many rules...

#include <Array.au3>

Global $aArray2D[1] ; <<<<<<<<<<<<<<<<<<<<<< 1D

Add2DEntry($aArray2D, "ABC[123CDE]")
Add2DEntry($aArray2D, "[AB]CD[][E][FG]H")
Add2DEntry($aArray2D, "ABCD[H1]EFG")
Add2DEntry($aArray2D, "ABC")
Add2DEntry($aArray2D, "ABC[123CDE]$a")
Add2DEntry($aArray2D, "ABC$?1EFG[123CDE]")
Add2DEntry($aArray2D, "ABC[123CDE]$")
Add2DEntry($aArray2D, "ABC&?[123CDE]")

_ArrayDisplay($aArray2D)

Func Add2DEntry(ByRef $aArray, $sAdd2DEntry)
;~  Local Static $Col
    Local $iMaxRows = UBound($aArray)
    $Col = UBound($aArray, 2) + 1 ; <<<<<<<<<<<<<<<<< Increment number of columns
    $sAdd2DEntry = StringRegExpReplace($sAdd2DEntry, "([£\$?&]+$)", "") ; remove unwanted characters only at the end of the string.
    Local $aTemp = StringRegExp($sAdd2DEntry, "([£\$?&]*\[.*?\]|[£\$?&]+(?!\[).|.)", 3)
    If UBound($aTemp) > $iMaxRows Then $iMaxRows = UBound($aTemp)
    ReDim $aArray[$iMaxRows][$Col]
    For $Row = 0 To $iMaxRows - 1
        If $Row < UBound($aTemp) Then $aArray[$Row][$Col - 1] = $aTemp[$Row]
    Next
EndFunc   ;==>Add2DEntry

.


[center]Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.[/center]

Share this post


Link to post
Share on other sites

So many rules...

 

Tell me about it! :(

I'm sorry for these complications, an initial look everything looks correct but i'm still testing if cover all. Thanks

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