Jump to content

Need to sort a string array


Recommended Posts

  • Moderators

sumitd,

Just use the array sorting function like this: ;)

#include <Array.au3>

Local $aList[7] = ["5.50.0.1","5.50.951.1","5.50.0.2","5.50.0.9","5.50.951.10","5.50.900.6","5.50.901.6"]

_ArraySort($aList)

_ArrayDisplay($aList)
Happy with that? :)

 

M23

Edited by Melba23
See below

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Link to comment
Share on other sites

  • Moderators

czardas,

Oops, sorry - forgot the array size declaration. Try now. :>

M23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Link to comment
Share on other sites

  • Moderators

sumitd,

If all the values begin with "5.50" then you could do something like this: ;)

#include <Array.au3>

Local $aList[7] = ["5.50.0.1","5.50.951.1","5.50.91.6","5.50.0.9","5.50.951.10","5.50.900.6","5.50.901.6"]

; Create a 2D array to work on
Local $aListNum[UBound($aList)][2]
For $i = 0 To UBound($aListNum) - 1
    $aListNum[$i][0] = $aList[$i] ; The full value
    $aListNum[$i][1] = Number(StringMid($aList[$i], 6)) ; The final 2 elements in decimal number form
Next

; Sort the numbers
_ArraySort($aListNum, 0, 0, 0, 1)

; Refill the original array
For $i = 1 To UBound($aList) - 1
    $aList[$i] = $aListNum[$i][0]
Next

_ArrayDisplay($aListNum)
How about that? :)

M23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Link to comment
Share on other sites

Here's what I cooked up.

;

#include <Array.au3>

Local $aList[7] = ["5.50.0.1","5.50.951.1","5.50.0.2","5.50.0.9","5.50.951.10","5.50.900.6","5.50.91.6"]
_VersionSortExample($aList)
_ArrayDisplay($aList)

Func _VersionSortExample(ByRef $aList)
    Local $iMax = UBound($aList)
    Local $aArray[$iMax][2], $aTemp, $sSegment

    For $i = 0 To $iMax -1
        $aTemp = StringSplit($aList[$i],".", 2)
        $aArray[$i][0] = $aList[$i]
        $aArray[$i][1] = ""
        For $j = 0 To 3
            $sSegment = $aTemp[$j]
            If $sSegment = "" Then $sSegment = "0"
            $aArray[$i][1] &= StringRight("00000000" & $sSegment, 8)
        Next
    Next
    _ArraySort($aArray, 0, 0, 0, 1)

    For $i = 0 To $iMax -1
        $aList[$i] = $aArray[$i][0]
    Next
EndFunc

;

It only works if there are exactly 4 numbers separated by dots. Numbers can range from

0.0.0.0 up to 99999999.99999999.99999999.99999999

No error cheking included (as of yet).

I may attempt to make a universal version using this idea later.

Edited by czardas
Link to comment
Share on other sites

Czardas,

I tried your code but get the below error,

$sSegment = $aTemp[$j]

$sSegment = ^ ERROR

 

This can occur if one of the values you modified was inconsistant with the four digit version numbers you  specified. Look again at what I said (there should be 4 numbers and 3 dots in each array element):

It only works if there are exactly 4 numbers separated by dots. Numbers can range from

0.0.0.0 up to 99999999.99999999.99999999.99999999

 

There are different possible ways to fix this. Either give an error warning that the numbers entered are not correct, or fix the broken input. Then the question is whether to add .0. where the numbers are inconsistant - I don't know. For example if you enter 1.4 then you could automatically change it to 1.4.0.0 or you could leave it as it is. Either way you have not explained how you wish to deal with these occurences.

I pressume 4 numbers are what you want.

Edited by czardas
Link to comment
Share on other sites

czardas,

I did not actually modify the content.

The array values are dynamically generated , these values are basically names of files ( e.g: 5.50.0.1, 5.40.980.2, 6.50.660.0,5.50.0.100,6.50.1.9,6.40.4.8 and so on)

Basically a function reads the names of the files from a remote localion and stores them in an array. Later it uses these names to form checkboxes in the GUI, which i need to be sorted.

Any suggestions on how to use your code for this purpose?

Link to comment
Share on other sites

Example :

#include <Misc.au3>
#include <Array.au3>
 
Local $avArray[6] = ["5.50.0.1", "5.40.980.2", "6.50.660.0", "5.50.0.100", "6.50.1.9", "6.40.4.8"]
bubbleSort($avArray)
 
_ArrayDisplay($avArray)
 
;https://en.wikipedia.org/wiki/Bubble_sort
Func bubbleSort(ByRef $avArray)
    Local $tmp = 0
    Do
        $fSwapped = False
        For $i = 1 To UBound($avArray) - 1
            ; if this pair is out of order
            If _VersionCompare($avArray[$i - 1], $avArray[$i]) = 1 Then
                ; swap them and remember something changed
                $tmp = $avArray[$i - 1]
                $avArray[$i - 1] = $avArray[$i]
                $avArray[$i] = $tmp
 
                $fSwapped = True
            EndIf
        Next
    Until Not $fSwapped
EndFunc   ;==>bubbleSort
Edit: The bubble sort algorithm may not be the best for this usage but it was for the example.

Br, FireFox.

Edited by FireFox
Link to comment
Share on other sites

When I run my example above it does not give an error. Anyway I have another example modified from the above. I had to strip the spaces out of your string for this to work. I don't know what they are doing there to be honest.

;

#include <Array.au3>

Local $sList = "5.50.0.1, 5.40.980.2, 6.50.660.0,5.50.0.100,6.50.1.9,6.40.4.8"
Local $aList = StringSplit($sList, ",", 2)

_VersionSortExample($aList)
If @error = 1 Then
    MsgBox(0, "Error", "Only one value was entered")
ElseIf @error = 2 Then
    MsgBox(0, "Error", "A version number was encountered with more than four values")
EndIf
_ArrayDisplay($aList)

Func _VersionSortExample(ByRef $aList)
    If Not IsArray($aList) Then Return SetError(1)
    Local $iMax = UBound($aList)
    Local $aArray[$iMax][2], $aTemp

    For $i = 0 To $iMax -1
        $aList[$i] = StringStripWS($aList[$i], 3) ; Method does not work with spaces
        If StringInStr($aList[$i], ".", 0, 4) Then Return SetError(2)
        If Not StringInStr($aList[$i], ".", 0, 3) Then $aList[$i] &= "..."

        $aTemp = StringSplit($aList[$i],".", 2)
        $aArray[$i][0] = $aList[$i]
        $aArray[$i][1] = ""
        For $j = 0 To 3
            $aArray[$i][1] &= StringRight("00000000" & $aTemp[$j], 8)
        Next
    Next
    _ArraySort($aArray, 0, 0, 0, 1)

    For $i = 0 To $iMax -1
        $aArray[$i][0] = StringRegExpReplace($aArray[$i][0], "[\.]+\z", "")
        $aList[$i] = $aArray[$i][0]
    Next
EndFunc

;

@FireFox _VersionCompair() sounds interesting. I'll have to take a look at that.

Edit

I cleaned up the code a little (it can probably still be simplified). It might not be what you want. It seems to do the same job as FireFox's code (the spaces mess that up too, so I notice, although FireFox's version caters for more than 4 version numbers, which is nice).

Edited by czardas
Link to comment
Share on other sites

@csardas supposedly it is better to apply the arraysort algorithm directly, this would spare two loops

Func __ArrayQuickSort2D(ByRef $avArray, ByRef $iStep, ByRef $iStart, ByRef $iEnd, ByRef $iSubItem, ByRef $iSubMax)
    If $iEnd <= $iStart Then Return

    ; QuickSort
    Local $vTmp, $L = $iStart, $R = $iEnd, $vPivot = $avArray[Int(($iStart + $iEnd) / 2)][$iSubItem], $fNum = IsNumber($vPivot)
    Do
        If $fNum Then
            ; While $avArray[$L][$iSubItem] < $vPivot
            While ($iStep * ($avArray[$L][$iSubItem] - $vPivot) < 0 And IsNumber($avArray[$L][$iSubItem])) Or (Not IsNumber($avArray[$L][$iSubItem]) And $iStep * StringCompare($avArray[$L][$iSubItem], $vPivot) < 0)
                $L += 1
            WEnd
            ; While $avArray[$R][$iSubItem] > $vPivot
            While ($iStep * ($avArray[$R][$iSubItem] - $vPivot) > 0 And IsNumber($avArray[$R][$iSubItem])) Or (Not IsNumber($avArray[$R][$iSubItem]) And $iStep * StringCompare($avArray[$R][$iSubItem], $vPivot) > 0)
                $R -= 1
            WEnd
        Else
            While ($iStep * StringCompare($avArray[$L][$iSubItem], $vPivot) < 0)
                $L += 1
            WEnd
            While ($iStep * StringCompare($avArray[$R][$iSubItem], $vPivot) > 0)
                $R -= 1
            WEnd
        EndIf

        ; Swap
        If $L <= $R Then
            For $i = 0 To $iSubMax
                $vTmp = $avArray[$L][$i]
                $avArray[$L][$i] = $avArray[$R][$i]
                $avArray[$R][$i] = $vTmp
            Next
            $L += 1
            $R -= 1
        EndIf
    Until $L > $R

    __ArrayQuickSort2D($avArray, $iStep, $iStart, $R, $iSubItem, $iSubMax)
    __ArrayQuickSort2D($avArray, $iStep, $L, $iEnd, $iSubItem, $iSubMax)
EndFunc   ;==>__ArrayQuickSort2D
Edited by Edano

[color=rgb(255,0,0);][font="'comic sans ms', cursive;"]FukuLeaks[/color][/font]

Link to comment
Share on other sites

@Edano

The basic _ArraySort function (or whatever internal sort function linked) wouldn't work here.

e.g:
5.900.5
is converted to 59005
 
6.1.3
is converted to 613
 
59005 > 613
whoever, the 2nd version is upper the first one.

If the OP's numbers are versions of course.

Br, FireFox.

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