繁体   English   中英

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

[英]better way to do this foreach using 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("]");

您应该研究使用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));

不是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,您也需要检查您是在第一项还是在最后一项。

你可以使用普通的for循环

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

创建一个数组到湖。使用ToArray()方法读取并将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("]");

如果你想简洁,你实际上可以使用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会更好地完成我的想法

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

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

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

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

我经常使用类似的东西:

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

这不是真正的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("]");

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM