如何在Delphi中让TStringList进行排序不同
我有一个简单的TStringList我做了一个TStringList.Sort就可以了.
然后我注意到下划线“_”在大写字母“A”之前排序.这与第三方软件包相反,该软件包正在排序相同的文本,并在A之后排序. 根据ANSI字符集,A-Z是字符65 – 90和_是95.所以看起来像第三方包使用该顺序,TStringList.Sort不是. 我钻进了TStringList.Sort的内容,它使用AnsiCompareStr(区分大小写)或AnsiCompareText(不区分大小写)进行排序.我尝试两种方法,将我的StringList的CaseSensitive值设置为true,然后将其设置为false.但在这两种情况下,“_”首先排序. 我无法想象这是TStringList中的错误.所以我还没有看到别的东西.可能是什么 我真正需要知道的是如何让我的TStringList进行排序,使其与其他程序包的顺序相同. 作为参考,我使用的是Delphi 2009,我在程序中使用Unicode字符串. 所以这里的最终答案是覆盖Ansi与任何你想要的比较(例如非ansi比较)如下: type TMyStringList = class(TStringList) protected function CompareStrings(const S1,S2: string): Integer; override; end; function TMyStringList.CompareStrings(const S1,S2: string): Integer; begin if CaseSensitive then Result := CompareStr(S1,S2) else Result := CompareText(S1,S2); end; 解决方法
定义“正常”.
i18n排序完全取决于您的地区. 所以我完全 PA同意,这是不是一个错误:默认排序行为的工作原理设计,让国际化才能正常工作. 像Gerry一样,TStringList.Sort使用AnsiCompareStr和AnsiCompareText(我将在几行中解释它如何做). 但是:TStringList是灵活的,它包含Sort,CustomSort和CompareStrings,这些都是虚拟的(所以你可以在后代类中覆盖它们) 在这个答案是一个比较功能,做你想要的: >区分大小写 CustomSort定义为: procedure TStringList.CustomSort(Compare: TStringListSortCompare); begin if not Sorted and (FCount > 1) then begin Changing; QuickSort(0,FCount - 1,Compare); Changed; end; end; 默认情况下,排序方法有一个非常简单的实现,通过默认的比较函数调用StringListCompareStrings: procedure TStringList.Sort; begin CustomSort(StringListCompareStrings); end; 所以,如果你定义自己的TStringListSortCompare兼容的比较方法,那么你可以定义自己的排序. type TStringListSortCompare = function(List: TStringList; Index1,Index2: Integer): Integer; 您可以使用StringListCompareStrings作为实现自己的指导: function StringListCompareStrings(List: TStringList; Index1,Index2: Integer): Integer; begin Result := List.CompareStrings(List.FList^[Index1].FString,List.FList^[Index2].FString); end; 所以,默认情况下,TStringList.Sort会延迟到TList.CompareStrings: function TStringList.CompareStrings(const S1,S2: string): Integer; begin if CaseSensitive then Result := AnsiCompareStr(S1,S2) else Result := AnsiCompareText(S1,S2); end; 然后使用下躺在Windows API函数CompareString用默认的用户区域LOCALE_USER_DEFAULT: function AnsiCompareStr(const S1,S2: string): Integer; begin Result := CompareString(LOCALE_USER_DEFAULT,PChar(S1),Length(S1),PChar(S2),Length(S2)) - 2; end; function AnsiCompareText(const S1,NORM_IGNORECASE,Length(S2)) - 2; end; 最后你需要比较功能.同样的限制: >区分大小写 这是代码: function StringListCompareStringsByOrdinalCharacterValue(List: TStringList; Index1,Index2: Integer): Integer; var First: string; Second: string; begin First := List[Index1]; Second := List[Index2]; if List.CaseSensitive then Result := CompareStr(First,Second) else Result := CompareText(First,Second); end; Delphi没有关闭,恰恰相反:通常它是一个非常灵活的架构. –jeroen (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |