#c# #backend #dto
#c# #серверная часть #dto
Вопрос:
Я пытаюсь извлечь инициалы из отображаемого имени, которое будет использоваться для отображения их инициалов. Мне это сложно, потому что строка представляет собой одно значение, содержащее одно слово или более. Как я могу этого добиться?
Пример:
‘Джон Смит’ => JS
‘Смит, Джон’ => SJ
‘John’ => J
‘Smith’ => S
public static SearchDto ToSearchDto(this PersonBasicDto person)
{
return new SearchDto
{
Id = new Guid(person.Id),
Label = person.DisplayName,
Initials = //TODO: GetInitials Code
};
}
Я использовал следующее решение: я создал вспомогательный метод, который позволил мне протестировать несколько случаев.
public static string GetInitials(this string name)
{
if (string.IsNullOrWhiteSpace(name))
{
return string.Empty;
}
string[] nameSplit = name.Trim().Split(new string[] { ",", " " }, StringSplitOptions.RemoveEmptyEntries);
var initials = nameSplit[0].Substring(0, 1).ToUpper();
if (nameSplit.Length > 1)
{
initials = nameSplit[nameSplit.Length - 1].Substring(0, 1).ToUpper();
}
return initials;
}
Комментарии:
1. Вы предполагаете, что всегда используете первую букву после пробела? Можете ли вы указать какие-либо (другие) подобные предположения? (В случае пробелов типичным шаблоном является «разделить, взять первый символ каждого элемента, объединить».)
2. В сторону: ложь, которую программисты верят в имена .
Ответ №1:
Или просто другой вариант в качестве метода расширения с небольшой проверкой работоспособности
Дано
public static class StringExtensions
{
public static string GetInitials(this string value)
=> string.Concat(value
.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries)
.Where(x => x.Length >= 1 amp;amp; char.IsLetter(x[0]))
.Select(x => char.ToUpper(x[0])));
}
Использование
var list = new List<string>()
{
"James blerg Smith",
"Michael Smith",
"Robert Smith 3rd",
"Maria splutnic Garcia",
"David Smith",
"Maria Rodriguez",
"Mary Smith",
"Maria Hernandez"
};
foreach (var name in list)
Console.WriteLine(name.GetInitials());
Вывод
JBS
MS
RS
MSG
DS
MR
MS
MH
Комментарии:
1. тест по этому поводу? benchmarkdotnet
Ответ №2:
Простой и понятный код и обрабатывает имена, которые содержат имя, отчество и фамилию, такие как «Джон Смит Уильям».
Протестируйте на:https://dotnetfiddle.net/kmaXXE
Console.WriteLine(GetInitials("John Smith")); // JS
Console.WriteLine(GetInitials("Smith, John")); // SJ
Console.WriteLine(GetInitials("John")); // J
Console.WriteLine(GetInitials("Smith")); // S
Console.WriteLine(GetInitials("John Smith William")); // JSW
Console.WriteLine(GetInitials("John H Doe")); // JHD
static string GetInitials(string name)
{
// StringSplitOptions.RemoveEmptyEntries excludes empty spaces returned by the Split method
string[] nameSplit = name.Split(new string[] { "," , " "}, StringSplitOptions.RemoveEmptyEntries);
string initials = "";
foreach (string item in nameSplit)
{
initials = item.Substring(0, 1).ToUpper();
}
return initials;
}
Комментарии:
1. проверка на:
"John Smith William"
?2. @Kiquenet, вы получаете JSW. Вы получаете другой результат?
3. @Джамал , никогда не изменяй строку внутри какого-либо цикла. это создаст новый объект string в куче памяти вместо изменения исходной строки по тому же адресу памяти. StringBuilder не создает новый объект в памяти, но динамически расширяет память для размещения измененной строки. Инициалы StringBuilder = новый StringBuilder(); foreach (элемент строки в разделителе имен) { инициалы. Добавить(item.Substring(0, 1). ToUpper()); } возвращает инициалы. toString();
4. @Neeraj Singh Chouhan, спасибо за подсказку о том, что код может быть оптимизирован для памяти, однако цель состоит в том, чтобы сделать код более понятным. Вы можете вносить изменения, если чувствуете себя обязанным.
Ответ №3:
Как насчет следующего:
void Main()
{
Console.WriteLine(GetInitials("John Smith"));
Console.WriteLine(GetInitials("Smith, John"));
Console.WriteLine(GetInitials("John"));
Console.WriteLine(GetInitials("Smith"));
}
private string GetInitials(string name)
{
if (string.IsNullOrWhiteSpace(name))
{
return string.Empty;
}
var splitted = name?.Split(' ');
var initials = $"{splitted[0][0]}{(splitted.Length > 1 ? splitted[splitted.Length - 1][0] : (char?)null)}";
return initials;
}
Вывод:
JS — SJ — J — S
Ответ №4:
приведенный ниже код взят отсюда. что делает код, так это берет первую букву каждого слова из строки и выводит ее в виде заглавных букв.
static void printInitials(String name)
{
if (name.Length == 0)
return;
// Since touuper() returns int,
// we do typecasting
Console.Write(Char.ToUpper(name[0]));
// Traverse rest of the string and
// print the characters after spaces.
for (int i = 1; i < name.Length - 1; i )
if (name[i] == ' 'amp;((i 1)!=name.Length))
Console.Write(" " Char.ToUpper(name[i 1]));
}