更好的方法来使用linq做这个foreach

时间:2010-10-28 10:08:03

标签: c# linq

嘿那里, 我有这个foreach循环不能100%工作。基本上我输出一个字符串。我的问题是我不想要sb.Append(“,”);要添加循环中的最后一条记录。有没有一种简单的方法可以使用linq来解决这个问题?

 sb.Append("Readings:[");
                    foreach (var reading in lake.Reading)
                    {
                        sb.Append("[");
                        sb.Append("\"");
                        sb.Append(reading.DateTime.ToString("dd-MMM-yy"));
                        sb.Append("\"");
                        sb.Append(",");
                        sb.Append(reading.Level);
                        sb.Append("]");
                //only insert this line if its the not the last record        sb.Append(",");
                    }
                sb.Append("]");

8 个答案:

答案 0 :(得分:5)

您应该考虑使用String.Join()String.Concat()。它使(逗号分隔的)列表更容易成为字符串。并与LINQ很好地合作。

var combine = from r in lake.Reading
              select String.Format("[\"{0:dd-MMM-yy}\",{1}]", r.DateTime, r.Level);
var str = String.Format("Readings:[{0}]", String.Join(",", combine));

答案 1 :(得分:1)

不是Linq方法,但你可以这样做:

sb.Append("Readings:[");

bool isFirst = true;
foreach (var reading in lake.Reading)
{
    if( isFirst == false )
    {
        sb.Append( "," );
    }
    isFirst = false;

    sb.Append("[");
    sb.Append("\"");
    sb.Append(reading.DateTime.ToString("dd-MMM-yy"));
    sb.Append("\"");
    sb.Append(",");
    sb.Append(reading.Level);
    sb.Append("]");
}
sb.Append("]");

即使使用Linq,您也需要检查您是在第一项还是最后一项。

答案 2 :(得分:0)

您可以使用普通的for循环

for(int i = 0; i< lake.Reading.count; i ++)

答案 3 :(得分:0)

使用ToArray()方法创建一个到Lake.Reading的数组,并将foreach更改为for。只需根据数组中元素的数量测试索引。

sb.Append("Readings:[");
Array list = late.Reading.ToArray();
                for (int i=0;i<list.Length;i++)
                {
                    var reading = list[i];
                    sb.Append("[");
                    sb.Append("\"");
                    sb.Append(reading.DateTime.ToString("dd-MMM-yy"));
                    sb.Append("\"");
                    sb.Append(",");
                    sb.Append(reading.Level);
                    sb.Append("]");
                    if (i!=list.Length-1)
                       sb.Append(",");
                }
            sb.Append("]");

答案 4 :(得分:0)

如果你想简洁,你实际上可以使用linq。但事件如果它是一个解决方案,它可能不是最好的。这样的事情应该有效:

lake.Reading.Aggregate(new StringBuilder(),
  (acc, value) => { return acc.AppendFormat("[{0},{1}],",value.Reading,value.Level); },
   acc => acc.Length > 1 ? (acc.Remove(acc.Length-1, 1).ToString()):string.Empty
  );

但是string.Join可以更好地完成我的想法

答案 5 :(得分:0)

我已经解决了这三种方式。

  • 在循环后修剪不需要的东西。

  • 使用“已启动”bool,例如,

    // Warning -- Air code fragment
    bool started = false;
    foreach (...) {
       if (!started)
          started = true;
       else
          sb.Append(",");
       // Rest of the loop
    }
  • 为StringBuilder创建了一个“启动”技巧的包装器。

答案 6 :(得分:0)

我通常使用类似的东西:

string s = lake.Reading
    .Select(r => "[\"" + r.DateTime.ToString("dd-MMM-yy") + "\"," + r.Level + "]")
    .Aggregate((n, m) => n + "," + m);

答案 7 :(得分:0)

这不是LINQ能够满足您的要求,但是string.Join

var formattedReadings = 
    from reading in lake.Reading
    select string.Format("[\"{0}\",{1}]", 
        reading.DateTime.ToString("dd-MMM-yy"), 
        reading.Level);

sb.Append("Readings:[");
sb.Append(string.Join(",", formattedReadings));
sb.Append("]");