c# – .NET以1,10和2开头排序字符串的最短方法是什么?
发布时间:2020-12-15 17:41:53 所属栏目:百科 来源:网络整理
导读:我需要对文件名进行排序,如下所示:1.log,2.log,10.log 但是当我使用OrderBy(fn = fn)时,它会将它们排序为: 1.log,10.log,2.log 我显然知道这可以通过写另一个比较者来完成,但是是否有一个更简单的方法来从字典排列顺序转变为自然排序? 编辑:目的是获得与
我需要对文件名进行排序,如下所示:1.log,2.log,10.log
但是当我使用OrderBy(fn => fn)时,它会将它们排序为: 我显然知道这可以通过写另一个比较者来完成,但是是否有一个更简单的方法来从字典排列顺序转变为自然排序? 编辑:目的是获得与Windows资源管理器中选择“按名称排序”相同的顺序. 解决方法
您可以使用Win32
CompareStringEx 功能.在Windows 7上,它支持您需要的排序.
您将使用P / Invoke: static readonly Int32 NORM_IGNORECASE = 0x00000001; static readonly Int32 NORM_IGNORENONSPACE = 0x00000002; static readonly Int32 NORM_IGNORESYMBOLS = 0x00000004; static readonly Int32 LINGUISTIC_IGNORECASE = 0x00000010; static readonly Int32 LINGUISTIC_IGNOREDIACRITIC = 0x00000020; static readonly Int32 NORM_IGNOREKANATYPE = 0x00010000; static readonly Int32 NORM_IGNOREWIDTH = 0x00020000; static readonly Int32 NORM_LINGUISTIC_CASING = 0x08000000; static readonly Int32 SORT_STRINGSORT = 0x00001000; static readonly Int32 SORT_DIGITSASNUMBERS = 0x00000008; static readonly String LOCALE_NAME_USER_DEFAULT = null; static readonly String LOCALE_NAME_INVARIANT = String.Empty; static readonly String LOCALE_NAME_SYSTEM_DEFAULT = "!sys-default-locale"; [DllImport("kernel32.dll",CharSet = CharSet.Unicode)] static extern Int32 CompareStringEx( String localeName,Int32 flags,String str1,Int32 count1,String str2,Int32 count2,IntPtr versionInformation,IntPtr reserved,Int32 param ); 然后,您可以创建一个使用SORT_DIGITSASNUMBERS标志的IComparer: class LexicographicalComparer : IComparer<String> { readonly String locale; public LexicographicalComparer() : this(CultureInfo.CurrentCulture) { } public LexicographicalComparer(CultureInfo cultureInfo) { if (cultureInfo.IsNeutralCulture) this.locale = LOCALE_NAME_INVARIANT; else this.locale = cultureInfo.Name; } public Int32 Compare(String x,String y) { // CompareStringEx return 1,2,or 3. Subtract 2 to get the return value. return CompareStringEx( this.locale,SORT_DIGITSASNUMBERS,// Add other flags if required. x,x.Length,y,y.Length,IntPtr.Zero,0) - 2; } } 然后,您可以在各种排序API中使用IComparer: var names = new [] { "2.log","10.log","1.log" }; var sortedNames = names.OrderBy(s => s,new LexicographicalComparer()); 您也可以使用StrCmpLogicalW这是Windows资源管理器使用的功能.自Windows XP以来一直可用 [DllImport("shlwapi.dll",CharSet = CharSet.Unicode)] static extern Int32 StrCmpLogical(String x,String y); class LexicographicalComparer : IComparer<String> { public Int32 Compare(String x,String y) { return StrCmpLogical(x,y); } } 比较简单,但对比较少. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |