One line declare, compare and return in c#

六月ゝ 毕业季﹏ 提交于 2020-02-08 10:06:30

问题


I am wondering if is possible to do something like the following code:

_ = 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)) ;

where names is the result of name.Split(' ').

Im not getting how to acces to this result without declaring it in a separated line like:

var names = name.Split(' ');

This line is what I want to avoid but also I dont want to call every time the Split function.

Anyone know how to resolve this or if it is even possible?

Thank you very much.


回答1:


You can do this with pattern matching:

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);

The var pattern is a catch-all for any type or value.

(I turned your calls to .Count() into .Length, as it's more idiomatic for arrays).

I'd recommend using ValueTuple instead of Tuple<T>:

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

Using C# 8's ranges, you can write this as:

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

(Note that splitting names using string.Split might not be the best way, and splitting them at all is probably a bad idea! See the other excellent answers here).




回答2:


Not literally answering the question, as canton7's answer using pattern matching does exactly what you want (declaring an inline variable using pattern matching), but this looks like what you actually want to do:

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);

This implements "the part after the last space, if present, is a last name". Note that this is not true for many last names, which can exist of multiple parts, just as first names.

In other words, you can't reasonably split "Jean Marc De Palma".




回答3:


@canton7's answer is a beauty, but this algorithm doesn't work for John von Neumann and even for your own name!

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

Names and surnames are versatile. Don't split it this way.



来源:https://stackoverflow.com/questions/58625038/one-line-declare-compare-and-return-in-c-sharp

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!