Sign in to follow this  
Followers 0
leomoon

Special Reversing Entries in an Array

5 posts in this topic

Hello,

Let's say we have an array like this:

Local $oWords[21] = [0, 1, 2, 3, 'AA', 'bb', '6', 7, 'dd', 'ee', 10, 'ff', 12, 13, 14, 15, 16, 17, 18, 19, 20]

I want to make it to check if there are continues series of entries that are numbers (more than 1), and only reverse that section. So it will become like this:

Local $oWords[21] = [3, 2, 1, 0, 'AA', 'bb', '7', 6, 'dd', 'ee', 10, 'ff', 20, 19, 18, 17, 16, 15, 14, 13, 12]

I tried for some time now. I can't figure out how to detect the continues series of entries that are numbers to reverse. Reversing part is easy which will be something like _ArrayReverse($avArray, 0, 3)...

Any ideas?

Tnx.

Share this post


Link to post
Share on other sites



#2 ·  Posted (edited)

Here's how I might go about it:

Local $oWords[21] = [0, 1, 2, 3, 'AA', 'bb', '6', 7, 'dd', 'ee', 10, 'ff', 12, 13, 14, 15, 16, 17, 18, 19, 20]
Local $str, $tempnum

For $x = 1 to UBound($oWords) - 1
If IsNumber($oWords[$x]) Then
     $tempnum = $oWords[$x] & "," & $tempnum
Else
     $str &= $tempnum & $oWords[$x] & ","
     $tempnum = ""
EndIf
Next
$str &= $tempnum
$str = StringTrimRight($str, 1)
MsgBox(0,"",$str)

Looks like you'll need to insert a line or two of code somewhere if you truly want to treat a numeric (like 7) the same as it's character representation ("7").

Edit: There's also one tiny (and very common) error in there ;) Hint: I have a preference for, and therefore am accustomed to using, 1-based arrays.

Edited by Spiff59

Share this post


Link to post
Share on other sites

#3 ·  Posted (edited)

How about this?

#include <Array.au3>

Local $oWords[21] = [0, 1, 2, 3, 'AA', 'bb', '6', 7, 'dd', 'ee', 10, 'ff', 12, 13, 14, 15, 16, 17, 18, 19, 20]

For $i = 0 To UBound($oWords) -1
    If IsNumber($oWords[$i]) Then
        $j = $i
        For $j = $i To UBound($oWords) -1
            If Not IsNumber($oWords[$j]) Then ExitLoop
        Next
        $j -= 1
        If $j <> $i Then _ArrayReverse($oWords, $i, $j)
        $i = $j
    EndIf
Next

_ArrayDisplay($oWords)

Or this which also reverses the 6th and 7th elements and I think actually does what you want.

#include <Array.au3>

Local $oWords[21] = [0, 1, 2, 3, 'AA', 'bb', '6', 7, 'dd', 'ee', 10, 'ff', 12, 13, 14, 15, 16, 17, 18, 19, 20]

For $i = 0 To UBound($oWords) -1
    If IsNumber($oWords[$i]) Or StringIsDigit($oWords[$i]) Then
        $j = $i
        For $j = $i To UBound($oWords) -1
            If Not IsNumber($oWords[$j]) And Not StringIsDigit($oWords[$j]) Then ExitLoop
        Next
        $j -= 1
        If $j <> $i Then _ArrayReverse($oWords, $i, $j)
        $i = $j
    EndIf
Next

_ArrayDisplay($oWords)

oops, just found a mistake in my second example. - Fixed.

Edited by czardas

Share this post


Link to post
Share on other sites

I was avoiding providing you with a canned "finished product" last night, but I had worked the kinks out of my example within a few minutes of posting. Staying away from calls to any of the _Array...() functions, including _ArrayReverse(), almost always results in a much faster routine:

#include <Array.au3>
Global $oWords[21] = [0, 1, 2, 3, 'AA', 'bb', '6', 7, 'dd', 'ee', 10, 'ff', 12, 13, 14, 15, 16, 17, 18, 19, 20]

$timer = TimerInit()
For $x = 0 to 10000
    NumReverse1($oWords)
Next
$timer = TimerDiff($timer) /1000
_ArrayDisplay($oWords, Round($timer, 2) & " seconds")

Global $oWords[21] = [0, 1, 2, 3, 'AA', 'bb', '6', 7, 'dd', 'ee', 10, 'ff', 12, 13, 14, 15, 16, 17, 18, 19, 20]
$timer = TimerInit()
For $x = 0 to 10000
    NumReverse2($oWords)
Next
$timer = TimerDiff($timer) /1000
_ArrayDisplay($oWords, Round($timer, 2) & " seconds")

;===============================================================================
Func NumReverse1(ByRef $oWords)
    Local $str, $tempnum
    For $x = 0 to UBound($oWords) - 1
        If StringIsDigit($oWords[$x]) Then
            $tempnum = $oWords[$x] & "," & $tempnum
        Else
            $str &= $tempnum & $oWords[$x] & ","
            $tempnum = ""
        EndIf
    Next
    $str = StringTrimRight($str & $tempnum, 1)
    $oWords = StringSplit($str, ",", 2)
EndFunc

Func NumReverse2(ByRef $oWords)
    For $i = 0 To UBound($oWords) -1
        If IsNumber($oWords[$i]) Or StringIsDigit($oWords[$i]) Then
            $j = $i
            For $j = $i To UBound($oWords) -1
                If Not IsNumber($oWords[$j]) And Not StringIsDigit($oWords[$j]) Then ExitLoop
            Next
            $j -= 1
            If $j <> $i Then _ArrayReverse($oWords, $i, $j)
            $i = $j
        EndIf
    Next
EndFunc

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