【问题标题】:LINQ .Where .Max and Writing to FileLINQ .Where .Max 和写入文件
【发布时间】:2021-07-13 19:35:13
【问题描述】:

我有一个程序将其输出写入日志文件到以下格式的文件夹:

Car7 Lap1 00-00-21-5290000 

一切正常,但我想在每辆车最快圈速的文件名后面加上一个#。为此,我将以下 LINQ 查询放在我的汽车对象中,以作用于 Car 的 List 属性:

public List<Lap> Laps { get; set; } = new List<Lap>();
public TimeSpan FastestLap => Laps.Where(lap => lap.Number is not null and not 0).Min(lap => lap.LapTime);

我正在使用 .Where 子句,因为 laps 有时可能为 null 或 0,当我写入磁盘时,最初似乎工作正常:

Car8 Lap39 00-01-07-8900000#

但是,只有 8 辆汽车被写入磁盘,而不是 20 辆汽车的全部字段。如果我只删除上面我的属性的 .Where 部分,所有的汽车和汽车文件夹都可以正确写入,除了第 0 圈文件通常被标记为最快圈(这是有道理的,因为它们包含不完整的时间)。

我的写入磁盘方法如下所示:

foreach (var car in carList)

{
     Directory.CreateDirectory(@$"{outputPath}\{logFileName}\Car{car.Number}");

     foreach (var lap in car.Laps)
     {
          using TextWriter tw = new StreamWriter(@$"{outputPath}\{logFileName}\Car{car.Number}\Car{car.Number} Lap{lap.Number} {lap.LapTime.ToString().Replace(":", "-").Replace(".", "-")}{(lap.LapTime == car.FastestLap ? "#" : "")}.csv");

          WriteCsvHeader(tw);

          foreach (var telemetryRecord in lap.UniqueTelemetryRecords)
          {
              WriteCsvLine(tw, lap, telemetryRecord);
          }
     }
}

有没有办法防止这种情况发生,以便将所有汽车和汽车文件夹写入磁盘?

【问题讨论】:

  • 如果LapTimeTimeSpan,你确定它可以编译Min(lap =&gt; lap.LapTime)

标签: c# linq


【解决方案1】:

在这种情况下,在检索值时使用 getter 执行更高级的逻辑。

替换这一行:

public TimeSpan FastestLap => Laps.Where(lap => lap.Number is not null and not 0).Min(lap => lap.LapTime);

有了这个:

public TimeSpan FastestLap
{
     get
     {
          if(Laps.Where(lap => lap.Number is not null and not 0).Count() > 0)
               return Laps.Where(lap => lap.Number is not null and not 0).Min(lap => lap.LapTime);
          else
               return Laps.Min(lap => lap.LapTime);
     }
}

这实质上是说,如果存在任何非零圈,则获取最低值。否则,它只会返回零值。

【讨论】:

  • @JMR 当然可以。请记住,该属性在这种情况下是只读的。所以没有办法手动更新它的值。您可以在这里了解更多信息:w3schools.com/cs/cs_properties.asp
【解决方案2】:

一种选择是在您的班级上实现IComparable&lt;T&gt;

public class Lap : IComparable<Lap>
{
    public int CompareTo(Lap other)
    {
         //if both have nulls or zero they are equal
        if((this.Number == null || this.Number == 0) && (other == null || other.Number == null || other.Number == 0) return 0;

        // If other is null or the other.Number is null or zero this instance is first in sort order
        if (other == null || other.Number == null || other.Number == 0) return -1;

        //if this instance has null or zero for the number and other doesn't this instance comes after other
        if((this.Number == null || this.Number == 0) && other != null && other.Number != null && other.Number != 0) return 1;

        //Comparison depends on this.LapTime to other.LapTime
        return LapTime.CompareTo(other.LapTime);
    }

    ......
}

然后您可以在List&lt;Lap&gt; 上致电.Sort(),您在列表中的第一项将是您的最快圈速,不为零也不为零。将 # 附加到列表中的第一项,您的类中不需要额外的方法。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-23
    • 1970-01-01
    • 1970-01-01
    • 2019-09-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多