Best way to remove the last character from a string built with stringbuilder

后端 未结 12 2387
-上瘾入骨i
-上瘾入骨i 2020-12-23 14:30

I have the following

data.AppendFormat(\"{0},\",dataToAppend);

The problem with this is that I am using it in a loop and there will be a t

12条回答
  •  情歌与酒
    2020-12-23 14:45

    Just use

    string.Join(",", yourCollection)
    

    This way you don't need the StringBuilder and the loop.




    Long addition about async case. As of 2019, it's not a rare setup when the data are coming asynchronously.

    In case your data are in async collection, there is no string.Join overload taking IAsyncEnumerable. But it's easy to create one manually, hacking the code from string.Join:

    public static class StringEx
    {
        public static async Task JoinAsync(string separator, IAsyncEnumerable 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();
            }
        }
    }
    

    If the data are coming asynchronously but the interface IAsyncEnumerable is not supported (like the mentioned in comments SqlDataReader), it's relatively easy to wrap the data into an IAsyncEnumerable:

    async IAsyncEnumerable<(object first, object second, object product)> ExtractData(
            SqlDataReader reader)
    {
        while (await reader.ReadAsync())
            yield return (reader[0], reader[1], reader[2]);
    }
    

    and use it:

    Task Stringify(SqlDataReader reader) =>
        StringEx.JoinAsync(
            ", ",
            ExtractData(reader).Select(x => $"{x.first} * {x.second} = {x.product}"));
    

    In order to use Select, you'll need to use nuget package System.Interactive.Async. Here you can find a compilable example.

提交回复
热议问题