我有以下
data.AppendFormat("{0},",dataToAppend);
问题是我在循环中使用它,并且会有一个试验逗号。删除尾部逗号的最佳方法是什么?
我是否必须将数据更改为字符串的子字符串呢?
我有以下
data.AppendFormat("{0},",dataToAppend);
问题是我在循环中使用它,并且会有一个试验逗号。删除尾部逗号的最佳方法是什么?
我是否必须将数据更改为字符串的子字符串呢?
Answers:
最简单,最有效的方法是执行以下命令:
data.Length--;
通过这样做,您可以将指针(即最后一个索引)移回一个字符,但不会更改对象的可变性。实际上,清除a StringBuilder
也是最好Length
的Clear()
方法(但实际上是为了清楚起见使用该方法,因为这是其实现的样子):
data.Length = 0;
再次,因为它不会更改分配表。想起来就像说,我不想再识别这些字节了。现在,即使调用ToString()
,它也无法识别超出其范围的任何内容Length
。这是一个可变的对象,比您提供的对象分配更多的空间,它是通过这种方式简单构建的。
data.Length = 0;
:确实是StringBuilder.Clear
这样,所以StringBuilder.Clear
为了清楚起见最好使用。
Clear()
,但很有趣。那是该方法的第一行Clear()
。但是,您是否知道接口实际上会发出一个return this;
。现在,那件事使我丧命。设置Length = 0
已经存在的参考的更改,为什么要返回自己?
Append
也返回自己。
只需使用
string.Join(",", yourCollection)
这样,您就不需要StringBuilder
和循环。
关于异步情况的长期补充。截至2019年,当数据异步传入时,这并不是罕见的设置。
如果您的数据位于异步集合中,则不会进行string.Join
重载IAsyncEnumerable<T>
。但是,很容易手动创建一个,从而从中string.Join
窃取代码:
public static class StringEx
{
public static async Task<string> JoinAsync<T>(string separator, IAsyncEnumerable<T> seq)
{
if (seq == null)
throw new ArgumentNullException(nameof(seq));
await using (var en = seq.GetAsyncEnumerator())
{
if (!await en.MoveNextAsync())
return string.Empty;
string firstString = en.Current?.ToString();
if (!await en.MoveNextAsync())
return firstString ?? string.Empty;
// Null separator and values are handled by the StringBuilder
var sb = new StringBuilder(256);
sb.Append(firstString);
do
{
var currentValue = en.Current;
sb.Append(separator);
if (currentValue != null)
sb.Append(currentValue);
}
while (await en.MoveNextAsync());
return sb.ToString();
}
}
}
如果数据是异步传入的,但IAsyncEnumerable<T>
不支持该接口(如注释中所述SqlDataReader
),则将数据包装到中相对容易IAsyncEnumerable<T>
:
async IAsyncEnumerable<(object first, object second, object product)> ExtractData(
SqlDataReader reader)
{
while (await reader.ReadAsync())
yield return (reader[0], reader[1], reader[2]);
}
并使用它:
Task<string> Stringify(SqlDataReader reader) =>
StringEx.JoinAsync(
", ",
ExtractData(reader).Select(x => $"{x.first} * {x.second} = {x.product}"));
为了使用Select
,您需要使用nuget包System.Interactive.Async
。在这里您可以找到一个可编译的示例。
string.Join(",", yourCollection)
仍然有一个,
结尾。因此上述ie string.Join(",", yourCollection)
效率很低,并且不能单独删除它。
循环后使用以下内容。
.TrimEnd(',')
或只是更改为
string commaSeparatedList = input.Aggregate((a, x) => a + ", " + x)
string.Join(",", input)
我更喜欢操纵stringbuilder的长度:
data.Length = data.Length - 1;
data.Length--
或--data.Length
?
--
或者++
您可以使用data.Length -= 1
,否则此答案也将起作用。
我建议您更改循环算法:
是的,循环完成后将其转换为字符串:
String str = data.ToString().TrimEnd(',');
最简单的方法是使用Join()方法:
public static void Trail()
{
var list = new List<string> { "lala", "lulu", "lele" };
var data = string.Join(",", list);
}
如果您确实需要StringBuilder,请在循环后修剪结尾逗号:
data.ToString().TrimEnd(',');
data.ToString().TrimEnd(',');
效率低下
string.Join(",", yourCollection)
?编辑:添加为答案。