Sign in to follow this  
Followers 0
sumitd

Need to sort a string array

32 posts in this topic

I need to sort a string array which contains values as [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]

Can anybody guide me on this please.

Share this post


Link to post
Share on other sites



Hi,

Welcome to the autoit forum :)

Can you tell us how would you like this to be sorted?

Br, FireFox.


 

OS : Win XP SP2 (32 bits) / Win 7 SP1 (64 bits) / Win 8 (64 bits) | Autoit version: latest stable / beta.
Hardware : Intel(R) Core(TM) i5-2400 CPU @ 3.10Ghz / 8 GiB RAM DDR3.

My UDFs : Skype UDF | TrayIconEx UDF | GUI Panel UDF | Excel XML UDF | Is_Pressed_UDF

My Projects : YouTube Multi-downloader | FTP Easy-UP | Lock'n | WinKill | AVICapture | Skype TM | Tap Maker | ShellNew | Scriptner | Const Replacer | FT_Pocket | Chrome theme maker

My Examples : Capture toolIP Camera | Crosshair | Draw Captured Region | Picture Screensaver | Jscreenfix | Drivetemp | Picture viewer

My Snippets : Basic TCP | Systray_GetIconIndex | Intercept End task | Winpcap various | Advanced HotKeySet | Transparent Edit control

 

Share this post


Link to post
Share on other sites

Hi Firefox,

I need the array to be sorted as

5.50.0.1

5.50.0.2

5.50.0.9

5.50.900.6

5.50.901.6

5.50.951.1

5.50.951.10,

regards,

sumitd

Share this post


Link to post
Share on other sites

#4 ·  Posted (edited)

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

Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind._______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

 

Share this post


Link to post
Share on other sites

czardas,

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

M23


Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind._______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

 

Share this post


Link to post
Share on other sites

#7 ·  Posted (edited)

I fixed that. I meant it's the numeric version sorting that's not working.

For example after sorting the following, we get:

[3]|5.50.900.6
[4]|5.50.91.6
[5]|5.50.951.1
 

Edited by czardas

Share this post


Link to post
Share on other sites

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


Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind._______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

 

Share this post


Link to post
Share on other sites

#9 ·  Posted (edited)

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

Share this post


Link to post
Share on other sites

Thanks M23 for the suggestion.

But problem is 1st two are not constant. and the array is very large :(

Czardas,

I tried your code but get the below error,

$sSegment = $aTemp[$j]

$sSegment = ^ ERROR

Share this post


Link to post
Share on other sites

#11 ·  Posted (edited)

But problem is 1st two are not constant.

Once again, can you give an example?

Edit: It should not be a problem with Melba23's example.

Edited by FireFox

 

OS : Win XP SP2 (32 bits) / Win 7 SP1 (64 bits) / Win 8 (64 bits) | Autoit version: latest stable / beta.
Hardware : Intel(R) Core(TM) i5-2400 CPU @ 3.10Ghz / 8 GiB RAM DDR3.

My UDFs : Skype UDF | TrayIconEx UDF | GUI Panel UDF | Excel XML UDF | Is_Pressed_UDF

My Projects : YouTube Multi-downloader | FTP Easy-UP | Lock'n | WinKill | AVICapture | Skype TM | Tap Maker | ShellNew | Scriptner | Const Replacer | FT_Pocket | Chrome theme maker

My Examples : Capture toolIP Camera | Crosshair | Draw Captured Region | Picture Screensaver | Jscreenfix | Drivetemp | Picture viewer

My Snippets : Basic TCP | Systray_GetIconIndex | Intercept End task | Winpcap various | Advanced HotKeySet | Transparent Edit control

 

Share this post


Link to post
Share on other sites

#12 ·  Posted (edited)

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

Share this post


Link to post
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?

Share this post


Link to post
Share on other sites

You can sort them using the _VersionCompare function.

Br, FireFox.


 

OS : Win XP SP2 (32 bits) / Win 7 SP1 (64 bits) / Win 8 (64 bits) | Autoit version: latest stable / beta.
Hardware : Intel(R) Core(TM) i5-2400 CPU @ 3.10Ghz / 8 GiB RAM DDR3.

My UDFs : Skype UDF | TrayIconEx UDF | GUI Panel UDF | Excel XML UDF | Is_Pressed_UDF

My Projects : YouTube Multi-downloader | FTP Easy-UP | Lock'n | WinKill | AVICapture | Skype TM | Tap Maker | ShellNew | Scriptner | Const Replacer | FT_Pocket | Chrome theme maker

My Examples : Capture toolIP Camera | Crosshair | Draw Captured Region | Picture Screensaver | Jscreenfix | Drivetemp | Picture viewer

My Snippets : Basic TCP | Systray_GetIconIndex | Intercept End task | Winpcap various | Advanced HotKeySet | Transparent Edit control

 

Share this post


Link to post
Share on other sites

#15 ·  Posted (edited)

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

 

OS : Win XP SP2 (32 bits) / Win 7 SP1 (64 bits) / Win 8 (64 bits) | Autoit version: latest stable / beta.
Hardware : Intel(R) Core(TM) i5-2400 CPU @ 3.10Ghz / 8 GiB RAM DDR3.

My UDFs : Skype UDF | TrayIconEx UDF | GUI Panel UDF | Excel XML UDF | Is_Pressed_UDF

My Projects : YouTube Multi-downloader | FTP Easy-UP | Lock'n | WinKill | AVICapture | Skype TM | Tap Maker | ShellNew | Scriptner | Const Replacer | FT_Pocket | Chrome theme maker

My Examples : Capture toolIP Camera | Crosshair | Draw Captured Region | Picture Screensaver | Jscreenfix | Drivetemp | Picture viewer

My Snippets : Basic TCP | Systray_GetIconIndex | Intercept End task | Winpcap various | Advanced HotKeySet | Transparent Edit control

 

Share this post


Link to post
Share on other sites

tricky as hell. there must be a clean mathematical solution


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

Share this post


Link to post
Share on other sites

#18 ·  Posted (edited)

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

Share this post


Link to post
Share on other sites

#19 ·  Posted (edited)

@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]

Share this post


Link to post
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.


 

OS : Win XP SP2 (32 bits) / Win 7 SP1 (64 bits) / Win 8 (64 bits) | Autoit version: latest stable / beta.
Hardware : Intel(R) Core(TM) i5-2400 CPU @ 3.10Ghz / 8 GiB RAM DDR3.

My UDFs : Skype UDF | TrayIconEx UDF | GUI Panel UDF | Excel XML UDF | Is_Pressed_UDF

My Projects : YouTube Multi-downloader | FTP Easy-UP | Lock'n | WinKill | AVICapture | Skype TM | Tap Maker | ShellNew | Scriptner | Const Replacer | FT_Pocket | Chrome theme maker

My Examples : Capture toolIP Camera | Crosshair | Draw Captured Region | Picture Screensaver | Jscreenfix | Drivetemp | Picture viewer

My Snippets : Basic TCP | Systray_GetIconIndex | Intercept End task | Winpcap various | Advanced HotKeySet | Transparent Edit control

 

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