我想要一个像OrderBy()这样的方法,它总是命令忽略重音字母,并像非重音一样看待它们.我已经尝试覆盖OrderBy(),但似乎我不能这样做,因为这是一个静态方法.
所以现在我想为OrderBy()创建一个自定义的lambda表达式,如下所示:
public static IOrderedEnumerable<TSource> ToOrderBy<TSource,TKey>( this IEnumerable<TSource> source,Func<TSource,TKey> keySelector) { if(source == null) return null; var seenKeys = new HashSet<TKey>(); var culture = new CultureInfo("pt-PT"); return source.OrderBy(element => seenKeys.Add(keySelector(element)),StringComparer.Create(culture,false)); }
但是,我收到此错误:
Error 2 The type arguments for method
‘System.Linq.Enumerable.OrderBy<TSource,TKey>(System.Collections.Generic.IEnumerable<TSource>,
System.Func<TSource,TKey>,
System.Collections.Generic.IComparer<TKey>)’ cannot be inferred from
the usage. Try specifying the type arguments explicitly.
似乎它不喜欢StringComparer.我怎么解决这个问题?
注意:
我已经尝试从here使用RemoveDiacritics()但我不知道在这种情况下如何使用该方法.所以我试着做一些像this这样的东西.
解决方法
OrderBy将keySelector作为第一个参数.此keySelector应为Func< string,T>.因此,您需要一个接受字符串的方法,并返回一个值,通过该值可以对枚举进行排序.
不幸的是,我不确定如何判断一个角色是否是一个“重音字母”. RemoveDiacritics对我的é不起作用.
因此,我们假设您有一个名为IsAccentedLetter的方法,用于确定字符是否为重音字母:
public bool IsAccentedLetter(char c) { // I'm afraid this does NOT really do the job return CharUnicodeInfo.GetUnicodeCategory(c) == UnicodeCategory.NonSpacingMark; }
所以你可以这样排序你的列表:
string[] myStrings = getStrings(); // whereever your strings come from var ordered = myStrings.OrderBy(s => new string(s.Select(c => IsAccentedLetter(c) ? ' ' : c).ToArray()),false));
lambda表达式接受一个字符串并返回相同的字符串,但用空格替换带重音的字母.
OrderBy现在按这些字符串对您的枚举进行排序,因此“忽略”重音字母.
更新:如果你有一个工作方法RemoveDiacritics(字符串s)返回字符串,并根据需要替换重音字母,你可以简单地调用OrderBy:
string[] mystrings = getStrings(); var ordered = myStrings.OrderBy(RemoveDiacritics,false));