benners Posted May 12, 2024 Posted May 12, 2024 I have a string that is used to load a combo or listview. As its a string sorting, the combo does not work correctly, neither does _ArraySort so I have created a function. The function works but it seems like a lof of faff for what it does. I think there must be a better\quicker way. Is there? It uses Melba's UDF here expandcollapse popup#include <Array.au3> #include 'ArrayMultiColSort.au3' ConsoleWrite('String: ' & _SortString("2|3|4|4 Part|7|8|9|12|13|15|21|28|31|35|OB1|NORTH|SOUTH|BORDER|3 Part|4 Past") & @crlf) Func _SortString($s_Sort, $b_AsArray = False) Local $s_AlphaCount = 0 Local $s_NumCount = 0 ; Step 1: Split the string into an array Local $as_Split = StringSplit($s_Sort, '|') ; loop to get the count of alpha string and mixed string For $i = 1 To $as_Split[0] If StringIsDigit(StringLeft($as_Split[$i], 1)) Then $s_NumCount += 1 Else $s_AlphaCount += 1 EndIf Next ; create two temp arrays Local $av_Numerical[$s_NumCount + 1][2] = [[$s_NumCount, '']] Local $as_Alpha[$s_AlphaCount + 1] = [$s_AlphaCount] ; reset the counts to use as array elements $s_NumCount = 1 $s_AlphaCount = 1 For $i = 1 To $as_Split[0] ; Check if the first character is a digit If StringIsDigit(StringLeft($as_Split[$i], 1)) Then ; check if the first char is a digit If StringIsDigit($as_Split[$i]) Then ; check if the full string is a digit $av_Numerical[$s_NumCount][0] = Number($as_Split[$i]) $s_NumCount += 1 Else ; alpha numeric Local $split = StringRegExp($as_Split[$i], "(\d+)\s*(\D+)", 3) $av_Numerical[$s_NumCount][0] = Number($split[0]) $av_Numerical[$s_NumCount][1] = $split[1] $s_NumCount += 1 EndIf Else ; alpha ; If the first character is not a digit, assume the string is purely alphabetic and store it in the second column $as_Alpha[$s_AlphaCount] = $as_Split[$i] $s_AlphaCount += 1 EndIf Next _ArraySort($as_Alpha, 0, 1) Local $aSortData[][] = [[0, 0], [1, 0]] _ArrayMultiColSort($av_Numerical, $aSortData, 1) Local $s_Ret = '' ; loop thorugh the array For $i = 1 To $av_Numerical[0][0] If $av_Numerical[$i][1] <> '' Then $s_Ret &= '|' & $av_Numerical[$i][0] & ' ' & $av_Numerical[$i][1] Else $s_Ret &= '|' & $av_Numerical[$i][0] EndIf Next $s_Ret &= '|' & _ArrayToString($as_Alpha, '|', 1) If $b_AsArray = True then Return StringSplit(StringTrimLeft($s_Ret, 1), '|') Return $s_Ret EndFunc ;==>_SortString
Solution Andreik Posted May 12, 2024 Solution Posted May 12, 2024 (edited) Something like this? #include <Array.au3> Local $aData = StringSplit('2|3|4|4 Part|7|8|9|12|13|15|21|28|31|35|OB1|NORTH|SOUTH|BORDER|3 Part|4 Past', '|', 2) NaturalCompare($aData) _ArrayDisplay($aData) Func NaturalCompare(ByRef $aData) Local $vTemp, $i, $j Local $hDll = DllOpen('Shlwapi.dll') For $i = 1 To UBound($aData) - 1 $j = $i While $j > 0 And DllCall($hDll, "int", "StrCmpLogicalW", "wstr", $aData[$j-1], "wstr", $aData[$j])[0] <> -1 $vTemp = $aData[$j] $aData[$j] = $aData[$j-1] $aData[$j-1] = $vTemp $j -= 1 WEnd Next DllClose($hDll) EndFunc Edited May 12, 2024 by Andreik SOLVE-SMART 1
benners Posted May 12, 2024 Author Posted May 12, 2024 Exactly like that How do people even know how to do this. I spent hours on my attempt Thanks
SOLVE-SMART Posted May 13, 2024 Posted May 13, 2024 (edited) Thank you @Andreik 👌 , for that function. I extented the $aData Array a litte bit by some 04, 004, etc. entries and I share the result (as screenshot), or better the comparison of _ArraySort and NaturalCompare for the community here. Just to give a better understanding what's the effect/difference 😇 . Local $aData = StringSplit('2|3|4|4 Part|7|8|9|12|13|004 Part|15|0004|04|4|004|21|28|31|35|OB1|NORTH|SOUTH|BORDER|3 Part|4 Past', '|', 2) Best regards Sven Edited May 13, 2024 by SOLVE-SMART Andreik 1 ==> AutoIt related: 🔗 GitHub, 🔗 Discord Server, 🔗 Cheat Sheet Spoiler 🌍 Au3Forums 🎲 AutoIt (en) Cheat Sheet 📊 AutoIt limits/defaults 💎 Code Katas: [...] (comming soon) 🎭 Collection of GitHub users with AutoIt projects 🐞 False-Positives 🔮 Me on GitHub 💬 Opinion about new forum sub category 📑 UDF wiki list ✂ VSCode-AutoItSnippets 📑 WebDriver FAQs 👨🏫 WebDriver Tutorial (coming soon)
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