用法OrderBy在LINQ中首先是西里尔字,然后是拉丁字

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了用法OrderBy在LINQ中首先是西里尔字,然后是拉丁字相关的知识,希望对你有一定的参考价值。

var listExample = new List<string>(){ "banana", "apple", "lemon", "orange", 
"cherry", "pear", "яблоко", "лимон", "груша", "банан", "апельсин", "вишня" };
listExample = listExample.OrderBy(x => x).ToList();

结果是

{ "apple", "banana", "cherry", "lemon", "orange", "pear", "апельсин", "банан", "вишня", "груша", "лимон", "яблоко" }

但需要俄罗斯的第一个订单然后像这样的英语

{ "апельсин", "банан", "вишня", "груша", "лимон", "яблоко", "apple", "banana", "cherry", "lemon", "orange", "pear" }

如何使用OrderBy获得该结果?

答案

如果工作是latin,您可以使用订单检查。

下面的代码返回所需的输出,它检查单词是否是IsCyrillic。

    var listExample = new List<string>(){ "banana", "apple", "lemon", "orange",  "cherry", 
                           "pear", "яблоко", "лимон", "груша", "банан", "апельсин", "вишня" };

    var result = listExample.OrderBy(x => x)
                    .Select(x => new {val = x, isCyrillic = Regex.IsMatch(x, @"p{IsCyrillic}")})
                    .OrderBy(x => !x.isCyrillic).Select(x => x.val);

    foreach (var str in result)
    {
        Console.WriteLine(str);
    }

检查这个小提琴的完整代码 - https://dotnetfiddle.net/9o4FJt

上述程序的输出是

橙色香蕉樱桃梨柠檬苹果苹果香蕉樱桃柠檬橙色梨

另一答案

对于一个相当“快速和肮脏”的方法,我可能会通过“包含西里尔字符的第一个索引”(使用int.MaxValue表示“无西里尔字母”),然后是常规排序(允许您使其不区分大小写等)来命令。

所以类似于:

var result = list.OrderBy(GetFirstCyrillicIndex).ThenBy(x => x).ToList();
...

private static int GetFirstCyrillicIndex(string text)
{
    // This could be written using LINQ, but it's probably simpler this way.
    for (int i = 0; i < text.Length; i++)
    {
        if (text[i] >= 0x400 && text[i] <= 0x4ff)
        {
            return i;
        }
    }
    return int.MaxValue;
}

完整的例子包括我尴尬的话:

using System;
using System.Collections.Generic;
using System.Linq;

class Test
{
    static void Main()
    {
        var list = new List<string> { 
            "banana", "apple", "lemon", "orange", 
            "cherry", "pear", "яблоко", "лимон",
            "груша", "банан", "апельсин", "вишня",
            "appleвишня", "вишняapple"
        };
        var result = list.OrderBy(GetFirstCyrillicIndex).ThenBy(x => x).ToList();
        foreach (var item in result)
        {
            Console.WriteLine(item);
        }
    }

    private static int GetFirstCyrillicIndex(string text)
    {
        // This could be written using LINQ, but it's probably simpler this way.
        for (int i = 0; i < text.Length; i++)
        {
            if (text[i] >= 0x400 && text[i] <= 0x4ff)
            {
                return i;
            }
        }
        return int.MaxValue;
    }
}

结果:

апельсин
банан
вишня
вишняapple
груша
лимон
яблоко
appleвишня
apple
banana
cherry
lemon
orange
pear
另一答案

为了替代,如果您不想实现全新的自定义顺序方法,则可以创建扩展方法并使用现有的顺序方法:

public static class MyExtensions
{
     public static IEnumerable<string> OrderByCyrillicFirst(this IEnumerable<string> list)
     {
         var cyrillicOrderedList = list.Where(l => string.IsNullOrEmpty(l) ? false : IsCyrillic(l[0])).OrderBy(l => l);
         var latinOrderedList = list.Where(l => string.IsNullOrEmpty(l) ? true : !IsCyrillic(l[0])).OrderBy(l => l);
         return cyrillicOrderedList.Concat(latinOrderedList);
     }

     public static IEnumerable<string> OrderByCyrillicFirstDescending(this IEnumerable<string> list)
     {
         var cyrillicOrderedList = list.Where(l => string.IsNullOrEmpty(l) ? false : IsCyrillic(l[0])).OrderByDescending(l => l);
         var latinOrderedList = list.Where(l => string.IsNullOrEmpty(l) ? true : !IsCyrillic(l[0])).OrderByDescending(l => l);
         return cyrillicOrderedList.Concat(latinOrderedList);
     }

    //cyrillic symbols start with code 1024 and end with 1273.
    private static bool IsCyrillic(char ch) =>
        ch >= 1024 && ch <= 1273;       
}

和用法:

var listExample = new List<string>(){ "banana", "apple", "lemon", "orange", "cherry", "pear", "яблоко", "лимон", "груша", "банан", "апельсин", "вишня" };

var result = listExample.OrderByCyrillicFirst();

输出:

橙色香蕉樱桃梨柠檬苹果苹果香蕉樱桃柠檬橙色梨

参考文献:DotNetFiddle exampleCyrillic Unicode Chart

以上是关于用法OrderBy在LINQ中首先是西里尔字,然后是拉丁字的主要内容,如果未能解决你的问题,请参考以下文章

Linq 首先按特定数字排序,然后按顺序显示所有其余部分

具有多个字段的 LINQ OrderBy

mysql删除一个西里尔字,选择一个西里尔字

西里尔字 俄语

SQL中order by;group up;like;关联查询join on的用法

C# LINQ 详解 From Where Select Group Into OrderBy Let Join