Лучший способ найти строку, которая сортирует после всех букв в текущей культуре

В C# я хочу получить список имен, отсортированных по алфавиту (без учета регистра) в текущей культуре, и иметь "поддельное имя", которое автоматически сортируется в конце этого списка.

Если бы для сортировки использовался ASCII, мы могли бы использовать '{', как это происходит после 'z', поэтому она всегда будет сортироваться после. Тем не менее, это не работает в целом для культурного вида.

Прямо сейчас я использую "ZZZZZZZZZZZ", который работает для английского языка, но я знаю, что это не правильный ответ - есть ли хороший способ сделать это?

(Я знаю, что одним из вариантов является просто положить их в конец после сортировки - к сожалению, это не просто в этом случае)

        var strings = new[] {"abc", "zzz", "ZZZ", "{"};

        var sortedStrings = strings.OrderBy(x => x, StringComparer.Create(new CultureInfo("en-GB"), ignoreCase: true));

        Console.WriteLine(string.Join(",", sortedStrings));
        // gives {,abc,zzz,ZZZ

2 ответа

Решение

Если я не ошибаюсь, последний символ в UTF-16 U+10FFFD (U+10FFFE а также U+10FFFF кажется зарезервированным) Так что вы можете сделать это, чтобы получить строку, которая, я думаю, всегда будет последней в своем роде:

string fakeName= char.ConvertFromUtf32(0x10FFFD);

Вы можете обернуть свою строку имени в тип, который может предоставить некоторые метаданные, например:

public class SortableName
{
    public string Name { get; set; }
    public bool IsFakeName { get; set; }
}

Вы можете расширить этот тип и использовать LINQ для сортировки коллекции на основе вашей бизнес-логики, например:

var names = new List<SortableName> { new SortableName { Name = "Test" }};
var sortedNames = names.OrderBy(n => n.IsFakeName)
                       .ThenBy(n => n.Name.ToLower()); //Case insensitivity

Затем вы можете проецировать это в коллекцию строк, сохраняя порядок:

var justNames = sortedNames.Select(n => n.Name);
Другие вопросы по тегам