Лучший способ найти строку, которая сортирует после всех букв в текущей культуре
В 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);