【问题标题】:One line declare, compare and return in c#一行在c#中声明、比较和返回
【发布时间】:2020-02-25 17:35:02
【问题描述】:

我想知道是否可以执行以下代码:

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

其中namesname.Split(' ') 的结果。

如果没有在单独的行中声明它,我不知道如何访问这个结果:

var names = name.Split(' ');

这一行是我想要避免的,但我也不想每次拆分函数时都调用。

有人知道如何解决这个问题,或者是否有可能?

非常感谢。

【问题讨论】:

  • 真正的问题是为什么要编写不可读的代码。您认为这样做节省的任何执行时间都被稍后读取和修改此代码所需的时间所浪费。另外,displayName 应该是 name 吗?
  • @CodeCaster 这只是为了知道是否有办法或是否有可能。无论如何,我不觉得它不可读。学习的方法就是尝试。

标签: c# lambda functional-programming


【解决方案1】:

您可以使用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);

var 模式适用于任何类型或值。

(我将您对 .Count() 的调用转换为 .Length,因为它更适用于数组)。

我建议使用ValueTuple 而不是Tuple&lt;T&gt;

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

使用C# 8's ranges,你可以这样写:

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

(请注意,使用string.Split 拆分名称可能不是最好的方法,并且完全拆分它们可能是个坏主意!请在此处查看其他出色的答案)。

【讨论】:

  • 太快了! :)))
  • 非常感谢你,这正是我想要的,你给了我三个变种:)
  • .Trim()RemoveEmptyEntries 会让它变得更好:)
【解决方案2】:

不是从字面上回答这个问题,因为 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);

这实现了“最后一个空格之后的部分,如果存在的话,是一个姓氏”。请注意,许多姓氏并非如此,这些姓氏可以由多个部分组成,就像名字一样。

换句话说,你不能合理地拆分“Jean Marc De Palma”。

【讨论】:

  • (纯粹是出于兴趣,如果您碰巧使用 C# 8,也可以使用范围而不是 .Substring
  • @canton 我已经读过这些,但还没有在实践中使用它们,所以我不会提倡它们。我变老了吗?
  • 我并不是建议您更改答案(因此是括号)。 C# 以如此之快的速度添加新语法,现在我认为我们都开始觉得有点老了!
  • 谢谢@CodeCaster 的回答:)。这看起来也不错。不要觉得老,我还很年轻,也需要跟上所有的快速变化!
  • @tymtam yeah I know。多部分姓氏(姓氏词缀)在我来自的地方很常见,“DeVries”和“de Vries”是两个不同的名字,存储和排序方式不同。
【解决方案3】:

@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

姓名和surnames 用途广泛。不要这样拆分。

【讨论】:

  • 是的,你完全正确!这也是我遇到的一个问题。例如,在西班牙语中,您的名字可以是“Alonso Fernando”,姓氏也可以是“Alonso”。或者你的名字可以只是“费尔南多”和姓“阿隆索”。我真的不知道它们在代码上有何不同。
猜你喜欢
  • 2013-04-16
  • 2013-06-09
  • 1970-01-01
  • 2013-04-13
  • 1970-01-01
  • 1970-01-01
  • 2021-05-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多