我写了这个字符串扩展一段时间后,我实际上得到了相当多的使用.
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();
}
Run Code Online (Sandbox Code Playgroud)
因为它现在在我的所有项目中,我想知道我是否可以做得更好.效率更高,还是会在任何情况下产生意想不到的结果?
切片.它的工作方式类似于Python的数组表示法.
"string"[start:end:step]
Run Code Online (Sandbox Code Playgroud)
许多其他语言也有类似的东西.string.Slice(1)相当于string.Substring(1).string.Substring(1,-1)修剪第一个和最后一个字符.string.Substring(null,null,-1)将扭转字符串.string.Substring(step:2)将返回一个字符串与每个其他字符...也类似于JS的切片但有一个额外的arg.
根据您的建议重新修改:
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();
}
Run Code Online (Sandbox Code Playgroud)
如果您有大量测试用例,并且希望尝试不同的实现,那么检测意外结果应该不是问题。
从 API 的角度来看,我会考虑可选参数而不是可空整数。
更新
仔细阅读代码后,我可以看到,将“start”和“end”赋予 null 值,在考虑“step”时具有特殊含义,因此,它们不能单独表示为可选 int 参数,但是,它们仍然可以是可选参数。
更仔细地查看代码后,您会发现它是一个有点时髦的 API,因为各个参数的值会相互影响。我之前的评论提到了这一点。您确实必须了解实现才能解决此问题,而不是通常良好的 API 方面。并且可能会造成难以阅读的体验。
我可以看到如何使用“step”来反转字符串,这可能很有用。但是反向扩展方法不是更好吗?更具可读性,更少的精神障碍。
| 归档时间: |
|
| 查看次数: |
1303 次 |
| 最近记录: |