amin84 Posted September 1, 2012 Posted September 1, 2012 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.
Spiff59 Posted September 1, 2012 Posted September 1, 2012 (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 September 1, 2012 by Spiff59
czardas Posted September 1, 2012 Posted September 1, 2012 (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 September 1, 2012 by czardas operator64 ArrayWorkshop
amin84 Posted September 1, 2012 Author Posted September 1, 2012 Thank you all. I was over-thinking it for some reason! Thank you again.
Spiff59 Posted September 1, 2012 Posted September 1, 2012 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: expandcollapse popup#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
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now