簡體   English   中英

OrderBy忽略重音字母

[英]OrderBy ignoring accented letters

我想要一個像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));
} 

但是,我收到此錯誤:

錯誤2方法'System.Linq.Enumerable.OrderBy <TSource,TKey>的類型參數(System.Collections.Generic.IEnumerable <TSource>,System.Func <TSource,TKey>,System.Collections.Generic.IComparer <TKey >)'無法從使用中推斷出來。 嘗試顯式指定類型參數。

似乎它不喜歡StringComparer 我怎么解決這個問題?

注意:

我已經嘗試過使用RemoveDiacritics()這里 ,但我不知道如何使用這種方法在這種情況下。 於是,我就做這樣的事情似乎不錯了。

OrderBykeySelector作為第一個參數。 這個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()), StringComparer.Create(culture, false));

lambda表達式接受一個字符串並返回相同的字符串,但用空格替換帶重音的字母。
OrderBy現在按這些字符串對您的枚舉進行排序,因此“忽略”重音字母。

更新:如果你有一個工作方法RemoveDiacritics(string s)返回字符串,並根據需要替換重音字母,你可以簡單地調用OrderBy

string[] mystrings = getStrings();
var ordered = myStrings.OrderBy(RemoveDiacritics, StringComparer.Create(culture, false));

解決了! 我得到了這個錯誤,因為要使用StringComparer元素在OrderBy()表達式中排序,該元素需要是一個string

因此,當我知道元素是一個字符串時,我會轉換為字符串,並使用RemoveDiacritics()方法忽略重音字母,並將其視為非重音字母。

public static IOrderedEnumerable<TSource> ToOrderBy<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector)
{
    if(!source.SafeAny())
        return null;

    return source.OrderBy(element => Utils.RemoveDiacritics(keySelector(element).ToString()));
}

為了garantee的RemoveDiacritics()我添加了一個工作正常HtmlDecode()線。

public static string RemoveDiacritics(string text)
{
    if(text != null)
        text = WebUtility.HtmlDecode(text);

    string formD = text.Normalize(NormalizationForm.FormD);
    StringBuilder sb = new StringBuilder();

    foreach (char ch in formD)
    {
        UnicodeCategory uc = CharUnicodeInfo.GetUnicodeCategory(ch);
        if (uc != UnicodeCategory.NonSpacingMark)
        {
            sb.Append(ch);
        }
    }

    return sb.ToString().Normalize(NormalizationForm.FormC);
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM