【问题标题】:Utilize C# 8 indices and ranges利用 C# 8 索引和范围
【发布时间】:2020-11-25 19:24:18
【问题描述】:

我正在尝试以有效的方式解决在线挑战。给定int的数组,我基本上必须以某种格式输出一个字符串。

我必须使字符串看起来像:(123) 456-7890(保证输入数组的长度正确)。

我发现了新的 C# 索引和范围,并尝试了类似的方法:

public static string GenerateOutput(int[] numbers)
{
    return $"({numbers[0..2]}) {numbers[3..5]}-{numbers[6..9]}";
}

但这不会返回所需的结果。如何将它们转换为字符串并返回正确的输出?

【问题讨论】:

  • 所以数组中的这些数字 - 它们可以有像 -38787123 这样的值吗?他们定义的范围是多少?
  • @MatthewWatson 不,该数组包含 10 个整数,其值为 0 到 9。
  • 您可以将所有数字转换为字符串以使用索引和格式 (numbers.Select(i => i.ToString())),但生成的解决方案效率不高。一个有效的解决方案将是一个冗长但明显的最小化分配的解决方案(例如,Span<char> s = stackalloc char["(000) 000-0000".Length]; s[0] = '('; s[1] = (char) (numbers[0] + '0'); ... return s.ToString(); -- new StringBuilder("(000) 000-0000"),如果你不想对Span 过于花哨)。当然,值得牢记的是,过早的优化是万恶之源。

标签: c# indexing indices


【解决方案1】:

主要问题是您将数组放入字符串中。数组上的ToString() 将生成描述类型的字符串,而不是其值的字符串。您需要连接这些数组。你可以创建一个本地函数,使用起来更方便:

string getNums (int start, int end) =>
    string.Join("", numbers[start..end]);

除此之外,您的索引在两端都包含在内。但是根据Microsoft

范围指定范围的开始和结束。范围是独占的,这意味着范围不包括结尾。

这不是排他的意思。 c-sharpcorner 说得更好:

范围运算符 .. 指定范围的开始(包括)和结束(不包括)。

我想他们这样做是有原因的,但从我的角度来看,这是一个非常令人惊讶的选择。

无论如何,考虑到这一点,您可以像这样实现本地函数:

var numbers = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 };

string getNums (int start, int end) =>
    string.Join("", numbers[start..end]);

return $"({getNums(0,3)}) {getNums(3,6)}-{getNums(6,10)}";

【讨论】:

  • 包含开始和排除结束的选择对应于计算字符之间插入点的索引,而不是字符本身。
  • @BenVoigt,你能详细说明一下吗?与(至少对我而言)更直观地考虑元素位置相比,考虑元素之间的点有什么优势。
  • 嗯,对于某些事情(指定插入点、光标位置等),有必要使用元素之间的点,而对于其他事情,它并没有真正伤害任何东西。 GetTextExtents 更自然地告诉您子字符串之后的边缘位置,而不是最后一个字符的位置(中心?基线中心?边界?)。对于命中测试,您需要比较字符之间的边界,而不是字符中心。当然,它使范围的长度等于 (end - start) 而不是 (end - start + 1)。空范围也更好。
  • @pwilcox 半开区间是范围的标准。它们有许多优点,但一个重要的优点是它可以很容易地表示一个空范围。
【解决方案2】:

如果你的数字是一个字符串,那么它们会更有用,这样它们就可以直接排列:

var s = string.Join("", numbers);

现在你可以使用范围来切割你的字符串:

var ph = $"(s[..3]}) {s[3..6]}-{s[^4..]}";

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-12-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-25
    • 1970-01-01
    相关资源
    最近更新 更多