【问题标题】:How to convert a C# list to a string with a fixed number of items per line using StringBuilder?如何使用 StringBuilder 将 C# 列表转换为每行具有固定项目数的字符串?
【发布时间】:2022-02-21 07:55:06
【问题描述】:

我正在尝试将数百个整数的List<int> 转换为一个字符串,该字符串在打印时每行具有指定数量的整数。我还在输出中的每个整数之间放置了“,”,并放置了左括号和右括号。如果 List 的 Count 不是每行项目数的倍数,则最后一行的项目数少于前一行。例如,如果 List 有 49 个整数,并且调用该方法在每行放置 11 个项目,则输出字符串在打印时将如下所示:

[3397, 3398, 3401, 3403, 3409, 3415, 3418, 3419, 3421, 3427, 3431, 
3437, 3439, 3442, 3443, 3446, 3453, 3455, 3459, 3466, 3473, 3481,
3482, 3487, 3489, 3493, 3494, 3497, 3503, 3505, 3506, 3513, 3518,
3521, 3523, 3543, 3545, 3551, 3554, 3561, 3563, 3566, 3569, 3574,
3578, 3579, 3587, 3589, 3595]

我已经编写了一个执行此操作的方法,并且输出看起来很棒,但我觉得我的代码可能遇到了意大利面条/jank 问题。有没有更好的方法来做到这一点,使用更少的代码行并使用 StringBuilder 而不是字符串连接?

public static string MakeBigStringFromList(List<int> input, 
            int itemsPerLine)
{
    int length = input.Count;
    List<int>.Enumerator intEnumerator = input.GetEnumerator();
    string bigReturnString = "[";
    if (length > 0)
    {
        intEnumerator.MoveNext();
        bigReturnString += intEnumerator.Current.ToString();
        if (length > 1)
        {
            bigReturnString += ", ";
        }
    }
    int firstTime = 1;

    int i = 1;
    while (i < length)
    {
        string line = "";
        int j = 0 + firstTime;
        if (i + itemsPerLine < length)
        {
            while (j < itemsPerLine)
            {
                intEnumerator.MoveNext();
                line += intEnumerator.Current.ToString() + ", ";
                i++;
                j++;
            }
            bigReturnString += line + "\n";
            firstTime = 0;
        }
        else
        {
            while (i < (length - 1))
            {
                intEnumerator.MoveNext();
                line += intEnumerator.Current.ToString() + ", ";
                i++;
            }
            intEnumerator.MoveNext();
            line += intEnumerator.Current.ToString();
            i++;
            bigReturnString += line;
            intEnumerator.Dispose();
        }
    }

    bigReturnString += "]";
    return bigReturnString;
}

【问题讨论】:

    标签: c# string list stringbuilder enumeration


    【解决方案1】:

    是的,你可以让它“一点点”更短,更易读,例如使用 LINQ

    var intsPerLine = list.Select((i, index) => (Integer: i, Index: index))
        .GroupBy(x => x.Index / 11, x => x.Integer.ToString())
        .Select(g => string.Join(", ", g) + ",");
    string result = $"[{string.Join(Environment.NewLine, intsPerLine).TrimEnd(',')}]";
    

    String.Join 在后台使用StringBuilder,所以这并不是低效的。

    说明:将所有ints分组为11个整数除法,选择int为字符串:

    GroupBy(x => x.Index / 11, x => x.Integer.ToString())
    

    这 11 个ints 用逗号连接,因此您会得到多个字符串:

    Select(g => string.Join(", ", g) + ",")
    

    在这些带有Environment.NewLine 的行字符串上使用String.Join 构建最终字符串。最后一个逗号被删除,然后用括号括起来:

    $"[{string.Join(Environment.NewLine, intsPerLine).TrimEnd(',')}]
    

    结果和你的一样(除了你用"\n",我用Environment.NewLine)。

    【讨论】:

      【解决方案2】:

      试试这个, 将整数列表中的值转换为字符串列表。

      List<string> sLst = iLst.ConvertAll<string>(delegate (int i) { return 
      i.ToString(); });
      

      可以通过转换为数组来打印捕获列表范围的值并显示它,

      Console.WriteLine(String.Join(",", sLst.GetRange(j, 11).ToArray()));
      

      【讨论】:

        【解决方案3】:

        不使用任何花哨的东西......

        public static string MakeBigStringFromList(List<int> input, int itemsPerLine)
        {
            StringBuilder sb = new StringBuilder("[");
            for(int i=0; i<input.Count; i++)
            {
                sb.Append(input[i]);
                if ((i+1) != input.Count)
                {
                    sb.Append(", ");
                    if ((i + 1) % itemsPerLine == 0)
                    {
                        sb.Append(Environment.NewLine);
                    }
                }                
            }
            sb.Append("]");
            return sb.ToString();
        }
        

        【讨论】:

          【解决方案4】:

          如果您使用的是 .NET6,则可以使用Chunk LINQ 方法:

          string BuildString(IEnumerable<int> list, int countPerLine)
          {
              return "[" 
                  + string.Join(Environment.NewLine, 
                      list.Chunk(countPerLine).Select(c => string.Join(", ", c) + ","))
                      .TrimEnd(',') 
                  + "]";
          }
          

          Chunk 会将输入拆分为最多包含countPerLine 个元素的子序列。然后string.Join(", ", c) + "," 从每个子序列中创建一行,最后string.Join(Environment.NewLine, ...) 合并这些行。

          【讨论】:

            猜你喜欢
            • 2014-10-09
            • 2022-01-16
            • 2020-04-18
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2020-01-03
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多