Sign in to follow this  
Followers 0
sbt

create new array, without / except values of an other one

23 posts in this topic

#1 ·  Posted (edited)

Hi,

if i have an array like this $array1 = "7,8,13,14,15,20" is it possible to make a new array start from 1 to 25 that don't contain one of the numbers in the $array1. Example $newarray = "1,2,3,4,5,6,9,10,11,12,16,17,18,19,21,22,23,24,25".

Is it possible to check if the numbers in the array are in continous order (ex. 1,2,3,4,5) and group them divided by "-", so if the array is $array3 = "3,4,5,6,9" the result should be $array4 = 3-6,9"

Thx in advance

sbt

Edited by sbt

Share this post


Link to post
Share on other sites



You're asking for arrays, but your examples suggest you want to use strings. (perhaps you could argue that those strings hold an array of numbers, but still) Which would you prefer?

Regardless of the answer what you are trying to do is very possible. There are two ways I can think of to do this: The first loops trough the exclusion array and calculates what numbers go between the excluded numbers, the other loops through all numbers and skips the excluded ones.

I'll throuw something together.

Share this post


Link to post
Share on other sites

#3 ·  Posted (edited)

Quick & Dirty:

#include <array.au3>
Global $aArrayIn[25] = [7, 8, 13, 14, 15, 20]
Global $aArrayOut[25] = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25]
Global $sOut = ""
For $iIndex = 0 To UBound($aArrayIn) - 1
    If IsNumber($aArrayIn[$iIndex]) Then $aArrayOut[$aArrayIn[$iIndex]-1] = "" ; set the excluded array elements to blank
Next
For $iIndex = UBound($aArrayOut) - 1 To 0 step -1
    If $aArrayOut[$iIndex] = "" Then _ArrayDelete($aArrayOut, $iIndex) ; delete the excluded array alement
Next

$iStart = 1
For $iIndex = 1 To UBound($aArrayOut) - 1
    If $aArrayOut[$iIndex] <> $aArrayOut[$iIndex-1] + 1 Then
        $iEnd = $aArrayOut[$iIndex-1]
        $sOut = $sOut & $iStart & "-" & $iEnd & ","
        $iStart = $aArrayOut[$iIndex]
    EndIf
Next
If $iStart = $aArrayOut[$iIndex-1] Then
    $sOut = $sOut & $iStart
Else
    $sOut = $sOut & $iStart & "-" & $aArrayOut[$iIndex-1]
EndIf
ConsoleWrite($sOut & @CRLF)

Displays: 1-6,9-12,16-19,21-25

Edited by water

My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (NEW 2017-04-18 - Version 1.4.8.0) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX (NEW 2017-02-27 - Version 1.3.1.0) - Download - General Help & Support - Example Scripts - Wiki
ExcelChart (2015-04-01 - Version 0.4.0.0) - Download - General Help & Support - Example Scripts
Excel - Example Scripts - Wiki
Word - Wiki
PowerPoint (2015-06-06 - Version 0.0.5.0) - Download - General Help & Support

Tutorials:
ADO - Wiki

 

Share this post


Link to post
Share on other sites

sbt,

An array is not a string. Sadly AutoIt doesn't handle strings as character arrays.

Array[0]="A"
$Array[1]="U"
;..etc..
$Array[6]="3"

In regards to seeing if the values are in sequential order, I would loop each array and check that the next number is only +1 above the last one.

Global $canContinue = True

Dim $arOne[5] = [1, 2, 3, 4, 5]
Dim $arTwo[5] = [1, 2, 3, 5, 4]

; First loop
Local $arLast = 1
For $i = 0 To UBound($arOne) -1
    ConsoleWrite($arOne[$i] & " - " & $arLast & @CRLF)
    If $arOne[$i] > ($arLast + 1) Then
        ConsoleWrite($arOne[$i] & " is not in sequential order..." & @CRLF)
        $canContinue = False
        ExitLoop
    Else
        $arLast = $arOne[$i]
    EndIf
Next

If $canContinue Then ConsoleWrite("$arOne is complete." & @CRLF)

; Second loop
Local $arLast = 1
For $i = 0 To UBound($arTwo) -1
    ConsoleWrite($arTwo[$i] & " - " & $arLast & @CRLF)
    If $arTwo[$i] > ($arLast + 1) Then
        ConsoleWrite($arTwo[$i] & " is not in sequential order..." & @CRLF)
        $canContinue = False
        ExitLoop
    Else
        $arLast = $arTwo[$i]
    EndIf
Next

If $canContinue Then ConsoleWrite("$arOne is complete." & @CRLF)

James

Share this post


Link to post
Share on other sites

I threw something together that somewhat resembles what you asked for.

I commented nearly every line, so if it's not exactly what you where looking for, at least you might get the idea of how to put smething together to do what you want.

#include <array.au3> ;just here for the _ArrayDisplay()
Global $aExclude[6] = [7,8,13,14,15,20] ;create an exlusion array
$aResult = _ArrayInvert($aExclude, 1, 25) ;Exclude the number is n the exclusion array from a new array ranging from 1 to 25
_ArrayDisplay($aResult) ;display result


Func _ArrayInvert(Const ByRef $aExclude, $iStart, $iEnd) ;Better name anyone?
    ;A basic check if the paramenter given seem valid.
    If Not IsArray($aExclude) Then Return SetError(1)
    If $iStart >= $iEnd Then Return SetError(2)
    If $iStart > $aExclude[0] Then Return SetError(3)
    If $iEnd < $aExclude[UBound($aExclude)-1] Then Return SetError(4)
    ;end check

    Local $aReturn[$iEnd-$iStart] ;Create an array to hold the result, that will always be big enough. (Should be safe to make it half this size, but meh)
    Local $n = 0 ;Create a variable that keeps track of the number of used indices in $aReturn
    For $i = 0 To UBound($aExclude)-1 ;Loop through the exclusion array.
        Switch $aExclude[$i] - $iStart
            Case 0 ;$iStart is in the exclude array.
                ;do nothing.
            Case 1 ;$iStart fits just between the last and current number on the exclude array.
                $aReturn[$n] = $iStart ;add number to result array.
                $n += 1 ;increase indice count for result array.
            Case Else ;There are at least 2 numbers between the last and current number on the exclude array.
                $aReturn[$n] = $iStart & "-" & $aExclude[$i]-1 ;add range to result array.
                $n += 1 ;increase indice count for result array.
        EndSwitch
        $iStart = $aExclude[$i]+1 ;Set $iStart to be bigger than the last checked number on the exclude array, then repeat.
    Next
    ;Once the loop finishes you may still need to add the last number ($iEnd), or the range between the last excluded number and $iEnd.
    Switch $aExclude[$i-1] - $iEnd
        Case 0 ;The last excluded number is equal to $iEnd
            ;do nothing.
        Case 1 ;The last excluded number is one smaller than $iEnd.
            $aReturn[$n] = $iEnd ;Add $iEnd to the result array.
            $n += 1 ;increase indice count for result array.
        Case Else ;There is a range between the last excluded number and $iEnd.
            $aReturn[$n] = $aExclude[$i-1]+1 & "-" & $iEnd ;Add range to the result array.
            $n += 1 ;increase indice count for result array.
    EndSwitch
    ReDim $aReturn[$n] ;Remove unused indices from the result array.
    Return $aReturn ;return the array.
EndFunc

Share this post


Link to post
Share on other sites

#6 ·  Posted (edited)

@Tvern and Water. Thx, thx, thx. I tried your code out and it's perfect. Now i try to implement it in my gui. I'm really new to autoit and when i see your functional code it seems always pretty easy; but to write it from scratch on is really hard. Thx again and i let you know.

Edited by sbt

Share this post


Link to post
Share on other sites

Well done Tvern !

I'm a bit slow but i got it ! Posted Image

[/size][/color]
[color=#1C2837][size=2]
#include <array.au3>
Global $aArray1[6] = [7, 8, 13, 14, 15, 20]
Global $aArray2[26] = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25]
Global $_Array3[1], $_Array4[1], $_J = 0
For $_I = 0 To UBound ( $aArray2 ) - 1
    If Not _AlreadyInArray ( $aArray1, $aArray2[$_I] ) Then 
        _ArrayAdd ( $_Array3, $aArray2[$_I] )
    Else
        _ArrayAdd ( $_Array3, ' ' )
    EndIf
Next

For $_I = 1 To UBound ( $_Array3 ) - 2
        ConsoleWrite ( $_I & " $_Array3[$_I] : " & $_Array3[$_I] & @Crlf )
    If $_Array3[$_I] +1 = $_Array3[$_I+1] Then 
       If not $_J Then $_J = $_Array3[$_I]
    Else
        If $_J Then _ArrayAdd ( $_Array4, $_J & '-' & $_Array3[$_I] )
        $_J = 0
    EndIf
Next
_ArrayDisplay ( $_Array4 )

Func _AlreadyInArray ( $_SearchArray, $_Item )
    $_Index = _ArraySearch ( $_SearchArray, $_Item ) 
    If @error Then   
        Return False
    Else  
        If  $_Index <> 0 Then
            Return True
        Else 
            Return False
        EndIf   
    EndIf
EndFunc ;==> _AlreadyInArray ( )[/size][/color]
[color=#1C2837][size=2]


AutoIt 3.3.14.2 X86 - SciTE 3.6.0WIN 8.1 X64 - Other Example Scripts

Share this post


Link to post
Share on other sites

I'm really new to autoit and when i see your functional code it seems always pretty easy; but to write it from scratch on is really hard.

It's always like that when you pick up something new. I still feel the same when I try something I havn't used much yet. (DLL's, and SQLite functions for instance)

I find it very helpfull to take existing code and take it apart, then try to rewrite it myself.

I also use allot of ConsoleWrite and _ArrayDisplays to see if variables and arrays have the value's I expect them to have.

Well done Tvern !

TY :graduated:

I made a small adjustment to your code to allow for non-range numbers:

#include <array.au3>
Global $aArray1[6] = [7, 8, 13, 15, 16, 20] ;in this case 14 is not a range.
Global $aArray2[26] = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25]
Global $_Array3[1], $_Array4[1], $_J = 0
For $_I = 0 To UBound ( $aArray2 ) - 1
    If Not _AlreadyInArray ( $aArray1, $aArray2[$_I] ) Then
        _ArrayAdd ( $_Array3, $aArray2[$_I] )
    Else
        _ArrayAdd ( $_Array3, ' ' )
    EndIf
Next

For $_I = 1 To UBound ( $_Array3 ) - 2
        ConsoleWrite ( $_I & " $_Array3[$_I] : " & $_Array3[$_I] & @Crlf )
    If $_Array3[$_I] +1 = $_Array3[$_I+1] Then
    If not $_J Then $_J = $_Array3[$_I]
    Else
        If $_J Then
            _ArrayAdd ( $_Array4, $_J & '-' & $_Array3[$_I] )
            $_J = 0
        ElseIf Number($_Array3[$_I]) Then ;add non-range numbers
            _ArrayAdd ( $_Array4, $_Array3[$_I] )
        EndIf
    EndIf
Next
_ArrayDisplay ( $_Array4 )

Func _AlreadyInArray ( $_SearchArray, $_Item )
    $_Index = _ArraySearch ( $_SearchArray, $_Item )
    If @error Then
        Return False
    Else
        If  $_Index <> 0 Then
            Return True
        Else
            Return False
        EndIf
    EndIf
EndFunc ;==> _AlreadyInArray ( )

Share this post


Link to post
Share on other sites

Here my version (not fully tested)!:

#include <Array.au3>
Dim $array1[6] = [7,8,13,14,15,20]
Dim $newarray[25] = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25]
$j = 0
For $i = 0 To UBound($array1) - 1
    While $j < UBound($newarray)
        If $newarray[$j] = $array1[$i] Then
            _ArrayDelete($newarray, $j)
            $j -= 2
        EndIf
        $j += 1
    WEnd
    $j = 0
Next
_ArraySort($newarray)
$s = 0
$string = $newarray[0]
For $i = 1 To UBound($newarray) - 1
    If $newarray[$s + 1] - $newarray[$s] <> 1 Then $string &= "-" &  $newarray[$s] & ","  & $newarray[$s + 1]
    $s += 1
Next
$string &= "-" & $newarray[$s]
ReDim $newarray[1]
$newarray[0] = $string
_ArrayDisplay($newarray)

Br,

UEZ


Please don't send me any personal message and ask for support! I will not reply!

Selection of finest graphical examples at Codepen.io

The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯

Share this post


Link to post
Share on other sites

#10 ·  Posted (edited)

Hi,

i checked it out and finally use the version of Tvern; it's working like a charm. Is it possible that it turns to me the exclusion string $aExclude[6] = [7,8,13,14,15,20] grouping the ones in sequential order divided by "-" too; result shoud be a newstring containing: 7-8,13-15,20

Thx in advance

sbt

Edited by sbt

Share this post


Link to post
Share on other sites

You'll have to come up with some code yourself next time. Even if it's a non-working attempt, but here is another one for you to study:

#include <array.au3> ;just here for the _ArrayDisplay()
Global $aExclude[6] = [7,8,13,14,15,20] ;create an exlusion array
$sExclude = _ArrayToRangeString($aExclude)
ConsoleWrite($sExclude & @CRLF)

Func _ArrayToRangeString(Const ByRef $aExclude)
    Local $sResult, $bRange
    For $i = 0 To UBound($aExclude)-2 ;loop through all numbers, except the last one
        If $aExclude[$i+1] = $aExclude[$i]+1 Then ;check if the next number is one higher than the current, indicating the start of a range.
            If Not $bRange Then ;if a range wans't active yet, start one.
                $bRange = True ;this indicates a range is now active
                $sResult &= $aExclude[$i] & "-" ;add first part of the range to the result string
            EndIf
            ;do nothing if a range is already active and not ending yet
        Else
            ;if the next number isn't in a range with the current one
            $sResult &= $aExclude[$i] & "," ;add current number to the string
            $bRange = False ;indicate there is no range currently active
        EndIf
    Next
    Return $sResult & $aExclude[$i] ;return the string with the last number added.
EndFunc

P.S: You could try turning that string into an array again, but it won't be easy at first.

Share this post


Link to post
Share on other sites

Here the version I posted earlier modified for you:

#include <Array.au3>
Dim $array1[6] = [7,8,13,14,15,20]
Dim $newarray[25] = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25]

MsgBox(0, "Test", ArrayExclude($array1, $newarray))

Func ArrayExclude($aA1, $aA2)
    Local $i, $j = 0
    For $i = 0 To UBound($aA1) - 1
        While $j < UBound($aA2)
            If $aA2[$j] = $aA1[$i] Then
                _ArrayDelete($aA2, $j)
                $j -= 2
            EndIf
            $j += 1
        WEnd
        $j = 0
    Next
    _ArraySort($aA2)
    $string = $aA2[0]
    For $i = 1 To UBound($aA2) - 1
        If $aA2[$i] - $aA2[$i -1] <> 1 Then $string &= "-" &  $aA2[$i - 1] & ","  & $aA2[$i]
    Next
     $string &= "-" & $aA2[$i - 1]
    Return $string
EndFunc

Br,

UEZ


Please don't send me any personal message and ask for support! I will not reply!

Selection of finest graphical examples at Codepen.io

The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯

Share this post


Link to post
Share on other sites

#13 ·  Posted (edited)

Thx again guys.

You'll have to come up with some code yourself next time.

@Tvern, you are wright, once i know a litte bit better Autoit i will do so. sbt Edited by sbt

Share this post


Link to post
Share on other sites

Hi,

I notice everyone have a fix implemented exclusion array (Global $aExclude[6] = [7,8,13,14,15,20] version by Tvern or Global $aArray1[6] = [7, 8, 13, 14, 15, 20] version by UEZ) and I tried a little bit around with your code and i need something simular.

So my question is, i have a gui with an Inputfield for the exclusions and I tried to read the Input as exclusion array, but it didn' t work for me.

Global $aExclude[6] = [GUICtrlRead(Input2)]

or

$aArray1[6] = [GUICtrlRead(Input2)]

furuseth

Share this post


Link to post
Share on other sites

#15 ·  Posted (edited)

GUICtrlRead(Input2) will only set $aArray1[6] to the content of GUICtrlRead(Input2)!

You have to convert the input to an array!

If your input is something like: 1,2,3,4,5 then use $aArray1 = StringSplit(GUICtrlRead(Input2), ",", 2)

Br,

UEZ

Edited by UEZ

Please don't send me any personal message and ask for support! I will not reply!

Selection of finest graphical examples at Codepen.io

The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯

Share this post


Link to post
Share on other sites

#16 ·  Posted (edited)

Hi, i always get an error parse function call. What did i wrong?

#include <ButtonConstants.au3>
#include <EditConstants.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#Region ### START Koda GUI section ### Form=
$Form1 = GUICreate("Form1", 441, 342, 192, 124)
$Input1 = GUICtrlCreateInput("7,8,13,14,15,20", 48, 32, 257, 21)
$Input2 = GUICtrlCreateInput("1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25", 48, 120, 257, 21)
$Button1 = GUICtrlCreateButton("Button1", 88, 192, 169, 25)
GUISetState(@SW_SHOW)
#EndRegion ### END Koda GUI section ###

While 1

    $msg = GUIGetMsg()
    Select
        Case $msg = $GUI_EVENT_CLOSE
            ExitLoop
        Case $msg = $Button1
                        $aArray1 = StringSplit(GUICtrlRead(Input1), ",", 2)
                $aArray2 = StringSplit(GUICtrlRead(Input2), ",", 2)
                        Dim $array1[6] = $aArray1
                Dim $newarray[25] = $aArray2
                MsgBox(0, "Test", ArrayExclude($array1, $newarray))

    EndSelect

WEnd

Func ArrayExclude($aA1, $aA2)
    Local $i, $j = 0
    For $i = 0 To UBound($aA1) - 1
        While $j < UBound($aA2)
            If $aA2[$j] = $aA1[$i] Then
                _ArrayDelete($aA2, $j)
                $j -= 2
            EndIf
            $j += 1
        WEnd
        $j = 0
    Next
    _ArraySort($aA2)
    $string = $aA2[0]
    For $i = 1 To UBound($aA2) - 1
        If $aA2[$i] - $aA2[$i -1] <> 1 Then $string &= "-" &  $aA2[$i - 1] & ","  & $aA2[$i]
    Next
     $string &= "-" & $aA2[$i - 1]
    Return $string
EndFunc
Edited by furuseth

Share this post


Link to post
Share on other sites

Here's a quick fix. I didn't look very closelt at how ArrayExclude works, so I might have left, or introduced an error, but it seems to work now.

I've commented the parts I changed throughout the script.

#include <ButtonConstants.au3>
#include <EditConstants.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <array.au3> ;needed for _ArrayDelete()
#Region ### START Koda GUI section ### Form=
$Form1 = GUICreate("Form1", 441, 342, 192, 124)
$Input1 = GUICtrlCreateInput("7,8,13,14,15,20", 48, 32, 257, 21)
$Input2 = GUICtrlCreateInput("1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25", 48, 120, 257, 21)
$Button1 = GUICtrlCreateButton("Button1", 88, 192, 169, 25)
GUISetState(@SW_SHOW)
#EndRegion ### END Koda GUI section ###

While 1

    $msg = GUIGetMsg()
    Select
        Case $msg = $GUI_EVENT_CLOSE
            ExitLoop
        Case $msg = $Button1
                Global $aArray1 = StringSplit(GUICtrlRead($Input1), ",", 2) ;added stringsplits, Added "$" for variables
                Global $aArray2 = StringSplit(GUICtrlRead($Input2), ",", 2)
                _ArrayDisplay($aArray1)
                _ArrayDisplay($aArray2)
;~              Dim $array1[6] = $aArray1
;~              Dim $newarray[25] = $aArray2
            MsgBox(0, "Test", ArrayExclude($aArray1, $aArray2)) ;Changed $array1 to $aArray1, changed $newarray to $aArray2

    EndSelect

WEnd

Func ArrayExclude($aA1, $aA2)
    Local $j = 0 ;no need to declare $i. For loops declare as local by default
    For $i = 0 To UBound($aA1) - 1
        While $j < UBound($aA2)
            If $aA2[$j] = $aA1[$i] Then
                _ArrayDelete($aA2, $j)
                ;removed $j -= 2 as it gave an error
            Else
                $j += 1
            EndIf
        WEnd
        $j = 0
    Next
;~  _ArraySort($aA2)
    Local $string = $aA2[0]
    For $i = 1 To UBound($aA2) - 1
        If $aA2[$i] - $aA2[$i -1] <> 1 Then $string &= "-" &  $aA2[$i - 1] & ","  & $aA2[$i]
    Next
    $string &= "-" & $aA2[$i - 1]
    Return $string
EndFunc

Share this post


Link to post
Share on other sites

Try this:

#include <ButtonConstants.au3>
#include <EditConstants.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <Array.au3>
#Region ### START Koda GUI section ### Form=
$Form1 = GUICreate("Form1", 441, 342, 192, 124)
$Input1 = GUICtrlCreateInput("7,8,13,14,15,20", 48, 32, 257, 21)
$Input2 = GUICtrlCreateInput("1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25", 48, 120, 257, 21)
$Button1 = GUICtrlCreateButton("Button1", 88, 192, 169, 25)
GUISetState(@SW_SHOW)
#EndRegion ### END Koda GUI section ###

Local $aArray1, $aArray2
While 1

    $msg = GUIGetMsg()
    Select
        Case $msg = $GUI_EVENT_CLOSE
            ExitLoop
        Case $msg = $Button1
                $aArray1 = StringSplit(GUICtrlRead($Input1), ",", 2)
                $aArray2 = StringSplit(GUICtrlRead($Input2), ",", 2)
;~              _ArrayDisplay($aArray1)
;~              _ArrayDisplay($aArray2)
                MsgBox(0, "Test", ArrayExclude($aArray1, $aArray2))
    EndSelect

WEnd

Func ArrayExclude($aA1, $aA2)
    Local $i, $j = 0
    For $i = 0 To UBound($aA1) - 1
        $aA1[$i] = Number($aA1[$i])
        While $j < UBound($aA2)
            $aA2[$j] = Number($aA2[$j])
            If $aA2[$j] = $aA1[$i] Then
                _ArrayDelete($aA2, $j)
                $j -= 2
            EndIf
            $j += 1
        WEnd
        $j = 0
    Next
    _ArraySort($aA2)
    $string = $aA2[0]
    For $i = 1 To UBound($aA2) - 1
        If $aA2[$i] - $aA2[$i -1] <> 1 Then $string &= "-" &  $aA2[$i - 1] & ","  & $aA2[$i]
    Next
     $string &= "-" & $aA2[$i - 1]
    Return $string
EndFunc

I had to modify my function otherwise sorting of array would not be correct.

Br,

UEZ


Please don't send me any personal message and ask for support! I will not reply!

Selection of finest graphical examples at Codepen.io

The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯

Share this post


Link to post
Share on other sites

Sorry, I must go now, I take a look later. furuseth

Share this post


Link to post
Share on other sites

#20 ·  Posted (edited)

Hi,

Uez your ones is working perfectly. The only minus is that i must define the entire rage ex. $input2=1,2,3,4,5,6,7 and so on, and i cannot define a rage in the gui. In the version of Tvern i could define the range (3rd line: $aResult = _ArrayInvert($aExclude, 1, 25)

So i tried to modify his code but i did not check it out. My modifications are:

Case $msg = $Button1

Global $aArray1 = StringSplit(GUICtrlRead($Input1), ",", 2)

Global $aExclude[6] = $aArray1 ;create an exlusion array

$aResult = _ArrayInvert($aExclude, 1, (GUICtrlRead($Input2))

_ArrayDisplay($aResult)

I'm always getting the error Missing subscript dimensions in "Dim" statement. The error is in this line of code: Global $aExclude[6] = $aArray1. Hope someone especially Tvern can help me

furuseth

#include <ButtonConstants.au3>
#include <EditConstants.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#Region ### START Koda GUI section ### Form=
$Form1 = GUICreate("Form1", 441, 342, 192, 124)
$Input1 = GUICtrlCreateInput("7,8,13,14,15,20", 48, 32, 257, 21)
$Input2 = GUICtrlCreateInput("25", 48, 120, 257, 21)
$Button1 = GUICtrlCreateButton("Button1", 88, 192, 169, 25)
GUISetState(@SW_SHOW)
#EndRegion ### END Koda GUI section ###

While 1

    $msg = GUIGetMsg()
    Select
        Case $msg = $GUI_EVENT_CLOSE
            ExitLoop
        Case $msg = $Button1
                Global $aArray1 = StringSplit(GUICtrlRead($Input1), ",", 2)
             Global $aExclude[6] = $aArray1 ;create an exlusion array
              $aResult = _ArrayInvert($aExclude, 1, (GUICtrlRead($Input2))
             _ArrayDisplay($aResult) ;display result

    EndSelect

WEnd

Func _ArrayInvert(Const ByRef $aExclude, $iStart, $iEnd) ;Better name anyone?
    ;A basic check if the paramenter given seem valid.
    If Not IsArray($aExclude) Then Return SetError(1)
    If $iStart >= $iEnd Then Return SetError(2)
    If $iStart > $aExclude[0] Then Return SetError(3)
    If $iEnd < $aExclude[UBound($aExclude)-1] Then Return SetError(4)
    ;end check

    Local $aReturn[$iEnd-$iStart] ;Create an array to hold the result, that will always be big enough. (Should be safe to make it half this size, but meh)
    Local $n = 0 ;Create a variable that keeps track of the number of used indices in $aReturn
    For $i = 0 To UBound($aExclude)-1 ;Loop through the exclusion array.
        Switch $aExclude[$i] - $iStart
            Case 0 ;$iStart is in the exclude array.
                ;do nothing.
            Case 1 ;$iStart fits just between the last and current number on the exclude array.
                $aReturn[$n] = $iStart ;add number to result array.
                $n += 1 ;increase indice count for result array.
            Case Else ;There are at least 2 numbers between the last and current number on the exclude array.
                $aReturn[$n] = $iStart & "-" & $aExclude[$i]-1 ;add range to result array.
                $n += 1 ;increase indice count for result array.
        EndSwitch
        $iStart = $aExclude[$i]+1 ;Set $iStart to be bigger than the last checked number on the exclude array, then repeat.
    Next
    ;Once the loop finishes you may still need to add the last number ($iEnd), or the range between the last excluded number and $iEnd.
    Switch $aExclude[$i-1] - $iEnd
        Case 0 ;The last excluded number is equal to $iEnd
            ;do nothing.
        Case 1 ;The last excluded number is one smaller than $iEnd.
            $aReturn[$n] = $iEnd ;Add $iEnd to the result array.
            $n += 1 ;increase indice count for result array.
        Case Else ;There is a range between the last excluded number and $iEnd.
            $aReturn[$n] = $aExclude[$i-1]+1 & "-" & $iEnd ;Add range to the result array.
            $n += 1 ;increase indice count for result array.
    EndSwitch
    ReDim $aReturn[$n] ;Remove unused indices from the result array.
    Return $aReturn ;return the array.
EndFunc
Edited by furuseth

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