C # Получить инициалы DisplayName

#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])); 
    }