Zedna Posted December 6, 2005 Posted December 6, 2005 I need something like AnsiCompare() in Delphiwhich uses WIN API CompareString with LOCALE_USER_DEFAULTI need sort array with names of peoples containing accents (diacritics)<array.au3> --> _ArraySort() is not working fineI searched forum for use of CompareString API but didn't find nothing Please is there some finished code for this, so I needn't do it from scratch?I mean ANSI compare and sort.Thank you Resources UDF ResourcesEx UDF AutoIt Forum Search
seandisanti Posted December 12, 2005 Posted December 12, 2005 I need something like AnsiCompare() in Delphiwhich uses WIN API CompareString with LOCALE_USER_DEFAULTI need sort array with names of peoples containing accents (diacritics)<array.au3> --> _ArraySort() is not working fineI searched forum for use of CompareString API but didn't find nothing Please is there some finished code for this, so I needn't do it from scratch?I mean ANSI compare and sort.Thank youdo you have some sample data?
GaryFrost Posted December 13, 2005 Posted December 13, 2005 (edited) here's something you might be able to work with, if you need to have multiple flags just bitor them Const $LOCALE_USER_DEFAULT = 0x400 Const $LOCALE_SYSTEM_DEFAULT = 0x800 ;~ Ignore case. Const $NORM_IGNORECASE = 0x1 ;~ Do not differentiate between Hiragana and Katakana characters. ;~ Corresponding Hiragana and Katakana characters compare as equal. Const $NORM_IGNOREKANATYPE = 0x40 ;~ Ignore nonspacing characters. Const $NORM_IGNORENONSPACE = 0x2 ;~ Ignore symbols. Const $NORM_IGNORESYMBOLS = 0x4 ;~ Do not differentiate between a single-byte character and the same ;~ character as a double-byte character. Const $NORM_IGNOREWIDTH = 0x8 ;~ Treat punctuation the same as symbols. Const $SORT_STRINGSORT = 0x1000 $str1 = "don't" $str2 = "do not" $a_ret = DllCall("kernel32.dll","int","CompareString","int",$LOCALE_USER_DEFAULT, "int", _ $NORM_IGNORECASE, "str", $str1, "int", -1, "str", $str2, "int", -1) ;~ If the function succeeds, the return value is one of the following values. ;~ The string pointed to by the lpString1 parameter is less in lexical value than the string ;~ pointed to by the lpString2 parameter.The string pointed to by lpString1 is equivalent in ;~ lexical value to the string pointed to by lpString2. The two strings are equivalent for ;~ collating purposes, though not necessarily identical.The string pointed to by lpString1 ;~ is greater in lexical value than the string pointed to by lpString2. ;~ If the function fails, the return value is zero. ;~ To get extended error information, call GetLastError. ;~ GetLastError may return one of the following error codes: ConsoleWrite($a_ret[0] & @LF) Edited December 14, 2005 by gafrost SciTE for AutoItDirections for Submitting Standard UDFs Don't argue with an idiot; people watching may not be able to tell the difference.
Zedna Posted December 14, 2005 Author Posted December 14, 2005 do you have some sample data?SeckarSečkářSedyShould be in this order but every accent letter is at end (is greater than Z) Resources UDF ResourcesEx UDF AutoIt Forum Search
Zedna Posted December 14, 2005 Author Posted December 14, 2005 here's something you might be able to work with, if you need to have multiple flags just bitor themThank you very much. I will look at this ... Resources UDF ResourcesEx UDF AutoIt Forum Search
Zedna Posted December 14, 2005 Author Posted December 14, 2005 here's something you might be able to work with, if you need to have multiple flags just bitor themIt's working fine I must also accomodate _ArraySort according to this new CompareString ... Resources UDF ResourcesEx UDF AutoIt Forum Search
Zedna Posted December 14, 2005 Author Posted December 14, 2005 here's something you might be able to work with, if you need to have multiple flags just bitor them I did it, it sotrs fine Thank you Gafrost. For optimize reason there should be DllOpen at begin of _ArraySortLocale and in CompareStringLocale should be new parameter $dll used in DllCall as handle of Dll so at each comparing row we didn't do internal DllOpen / DllClose in DllCall But for my use it's OK. expandcollapse popupConst $LOCALE_USER_DEFAULT = 0x400 #include <Array.au3> Dim $pole[4] = ['Zedna','Šilhan','Sečkář', 'Sedan'] _ArrayDisplay($pole,'before') _ArraySort($pole) _ArrayDisplay($pole,'after normal') _ArraySortLocale($pole) _ArrayDisplay($pole,'after locale') Func CompareStringLocale($s1, $s2, $ignore_case = 0) $a_ret = DllCall("kernel32.dll","int","CompareString","int",$LOCALE_USER_DEFAULT, "int", _ $ignore_case, "str", $s1, "int", -1, "str", $s2, "int", -1) Return $a_ret[0] EndFunc Func _ArraySortLocale(ByRef $a_Array, $i_Decending = 0, $i_Base = 0, $i_UBound = 0) ; Set to ubound when not specified If Not IsArray($a_Array) Then SetError(1) Return 0 EndIf Local $last = UBound($a_Array) - 1 If $i_UBound < 1 Or $i_UBound > $last Then $i_UBound = $last __ArrayQSort1Locale($a_Array, $i_Base, $i_UBound) If $i_Decending Then _ArrayReverse($a_Array, $i_Base, $i_UBound) Return 1 EndFunc;==>_ArraySort ; Private Func __ArrayQSort1Locale(ByRef $array, ByRef $left, ByRef $right) If $right - $left < 10 Then ; InsertSort - fastest on small segments (= 25% total speedup) Local $i, $j, $t For $i = $left + 1 To $right $t = $array[$i] $j = $i While $j > $left _ And CompareStringLocale(String($array[$j - 1]),String($t)) = 3; String($array[$j - 1]) > String($t) $array[$j] = $array[$j - 1] $j = $j - 1 Wend $array[$j] = $t Next Return EndIf ; QuickSort - fastest on large segments Local $pivot = $array[Int(($left + $right)/2)];, $t Local $L = $left Local $R = $right Do While CompareStringLocale(String($array[$L]),String($pivot)) = 1; String($array[$L]) < String($pivot) $L = $L + 1 Wend While CompareStringLocale(String($array[$R]),String($pivot)) = 3; String($array[$R]) > String($pivot) $R = $R - 1 Wend ; Swap If $L <= $R Then $t = $array[$L] $array[$L] = $array[$R] $array[$R] = $t $L = $L + 1 $R = $R - 1 EndIf Until $L > $R __ArrayQSort1Locale($array, $left, $R) __ArrayQSort1Locale($array, $L, $right) EndFunc Resources UDF ResourcesEx UDF AutoIt Forum Search
Koder Posted December 14, 2005 Posted December 14, 2005 I brought this up ages ago. Sorting should always be case sensitive otherwise the resulting sort is 'undefined'. _ArraySort() returns a differently sorted list depending on the original order because it is not case sensitive. I already have a string compare function but the DLLcall might be faster, Ill have to try that out, thanks.
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