Одну строку объявляем, сравниваем и возвращаем в c # - PullRequest
0 голосов
/ 30 октября 2019

Мне интересно, возможно ли сделать что-то вроде следующего кода:

_ = name.Split(' ') => names.Count() > 1 ?
                new Tuple<string, string>(string.Join(" ", names.Take(names.Count() - 1)), names.Last()) :
                new Tuple<string, string>(name, string.Empty)) ;

, где names - результат name.Split(' ').

Я не понимаю, как получить доступк этому результату без объявления его в отдельной строке, например:

var names = name.Split(' ');

Эта строка - то, чего я хочу избежать, но также я не хочу вызывать каждый раз функцию Split.

Кто-нибудь знаеткак решить эту проблему или если это вообще возможно?

Большое спасибо.

Ответы [ 3 ]

4 голосов
/ 30 октября 2019

Вы можете сделать это с помощью сопоставления с образцом :

var result = s.Split(' ') is var names && names.Length > 1 ? 
    new Tuple<string, string>(string.Join(" ", names.Take(names.Length - 1)), names.Last()) :
    new Tuple<string, string>(displayName, string.Empty);

Шаблон var является универсальным для любого типа или значения.

(Iпревратил ваши звонки в .Count() в .Length, поскольку это более идиоматично для массивов).

Я бы рекомендовал использовать ValueTuple вместо Tuple<T>:

var result = s.Split(' ') is var names && names.Length > 1 ? 
    (string.Join(" ", names.Take(names.Length - 1)), names.Last()) :
    (displayName, string.Empty);

Используя диапазоны C # 8 , вы можете записать это как:

var result = s.Split(' ') is var names && names.Length > 1 ? 
    (string.Join(" ", names[0..^1]), names[^1]) :
    (displayName, string.Empty);

(Обратите внимание, что разделение имен с использованием string.Split может быть не лучшим способом, и разделение их вообщеэто, вероятно, плохая идея! Смотрите другие отличные ответы здесь).

3 голосов
/ 30 октября 2019

Не буквально отвечая на вопрос, поскольку ответ canton7 с использованием сопоставления с образцом делает именно то, что вы хотите (объявление встроенной переменной с помощью сопоставления с образцом), но это выглядит так, как вы на самом деле хотите:

var name = "foo bar baz";
var i = name.LastIndexOf(' ');
var firstNames = i > -1 ? name.Substring(0, i) : name;
var lastName = i > -1 ? name.Substring(i + 1, name.Length - i - 1) : "";

var t = new Tuple<string, string>(firstNames, lastName);

Это реализует "часть после последнего пробела, если присутствует, является фамилией". Обратите внимание, что это не так для многих фамилий, которые могут состоять из нескольких частей, как и имена.

Другими словами, вы не можете разумно разделить «Жан Марк де Пальма».

2 голосов
/ 30 октября 2019

@ canton7 - прекрасный ответ, но этот алгоритм не работает для Джона фон Неймана и даже для вашего собственного имени!

var name = "Jesús Narváez Tamés";
var displayName = "TODO";


var fl = name.Split(' ') is var names && names.Count() > 1 
            ? (string.Join(" ", names.Take(names.Count() - 1)), names.Last())
            : (displayName, string.Empty);

Console.WriteLine($"First: {fl.Item1}");
Console.WriteLine($"Last: {fl.Item2}");
First: Jesús Narváez
Last: Tamés

Имена и фамилии являютсяуниверсальны. Не разбивайте это так.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...