c# - 有什么方法可以改进这个字符串切片方法吗?

标签 c# string slice

我不久前写了这个字符串扩展,实际上我从中得到了很多用处。

public static string Slice(this string str, int? start = null, int? end = null, int step = 1)
{
    if (step == 0) throw new ArgumentException("Step cannot be zero.", "step");

    if (start == null)
    {
        if (step > 0) start = 0;
        else start = str.Length - 1;
    }
    else if (start < 0)
    {
        if (start < -str.Length) start = 0;
        else start += str.Length;
    }
    else if (start > str.Length) start = str.Length;

    if (end == null)
    {
        if (step > 0) end = str.Length;
        else end = -1;
    }
    else if (end < 0)
    {
        if (end < -str.Length) end = 0;
        else end += str.Length;
    }
    else if (end > str.Length) end = str.Length;

    if (start == end || start < end && step < 0 || start > end && step > 0) return "";
    if (start < end && step == 1) return str.Substring((int)start, (int)(end - start));

    int length = (int)(((end - start) / (float)step) + 0.5f);
    var sb = new StringBuilder(length);
    for (int i = (int)start, j = 0; j < length; i += step, ++j)
        sb.Append(str[i]);
    return sb.ToString();
}

因为它现在在我所有的项目中,我想知道我是否可以做得更好。更高效,还是无论如何都会产生意想不到的结果?


切片。它的工作方式类似于 Python 的数组表示法。

 "string"[start:end:step]

许多其他语言也有类似的东西。 string.Slice(1) 等同于 string.Substring(1)string.Substring(1,-1) 删除第一个和最后一个字符。 string.Substring(null,null,-1) 将反转字符串。 string.Substring(step:2) 将返回一个每隔一个字符的字符串...也类似于 JS's slice但有一个额外的参数。


根据您的建议重新修改:

public static string Slice(this string str, int? start = null, int? end = null, int step = 1)
{
    if (step == 0) throw new ArgumentException("Step size cannot be zero.", "step");

    if (start == null) start = step > 0 ? 0 : str.Length - 1;
    else if (start < 0) start = start < -str.Length ? 0 : str.Length + start;
    else if (start > str.Length) start = str.Length;

    if (end == null) end = step > 0 ? str.Length : -1;
    else if (end < 0) end = end < -str.Length ? 0 : str.Length + end;
    else if (end > str.Length) end = str.Length;

    if (start == end || start < end && step < 0 || start > end && step > 0) return "";
    if (start < end && step == 1) return str.Substring(start.Value, end.Value - start.Value);

    var sb = new StringBuilder((int)Math.Ceiling((end - start).Value / (float)step));
    for (int i = start.Value; step > 0 && i < end || step < 0 && i > end; i += step)
        sb.Append(str[i]);
    return sb.ToString();
}

最佳答案

如果您有大量测试用例,那么如果您想尝试不同的实现,那么检测意外结果应该不是问题。

从 API 的角度来看,我会考虑 optional arguments而不是可为空的整数。

更新

仔细阅读代码后,我发现给“start”和“end”赋值null,在考虑“step”时有特殊意义,因此,它们不能单独表示为可选的int参数,但是,它们仍然可以是可选参数。

仔细查看代码后,它是一个有点古怪的 API,因为各个参数的值会相互影响。我之前的评论暗示了这一点。你真的必须知道实现才能解决这个问题,这通常不是一个好的 API 方面。并且可能会带来困难的可读性体验。

我可以看到如何使用“step”来反转字符串,这可能很有用。但是反向扩展方法不是更好吗?更具可读性,更少的心理障碍。

关于c# - 有什么方法可以改进这个字符串切片方法吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4270928/

相关文章:

c# - 在用户未登录时将文件复制到映射的驱动器(计划任务)

C#:从泛型调用外部程序集中的重载方法

java - 检测字符串中的重复字符

concatenation - 如何在 TensorFlow 中对批处理进行切片并对每个切片应用操作

python - 遍历 ndarray 的切片

C# Azure Cosmos DB - 如何选择大量数据(~100,000 个文档)

c# - 返回 IHttpActionResult 与 IEnumerable<Item> 与 IQueryable<Item>

c# - 如果一个字符串存在于大量对象列表中,比较最快的(性能)方法是什么?

python - 在 html 元素上使用 text_content() 时避免连续出现单词的可靠方法

go - 紧急情况:运行时错误:索引超出范围[0],长度为0