代码之家  ›  专栏  ›  技术社区  ›  ewok

基于种子和上一个值创建值列表

  •  -1
  • ewok  · 技术社区  · 1 月前

    我有一个对象(触发器),其中包含一个名为 GetNextFireTime(DateTimeOffset after) ,在给定输入后触发器下次触发时返回。我的目标是,给定一个未知大小的时间列表的输入 n ,以及开始时间,以确保时间列表与第一个时间匹配 n 触发器在开始时间后触发的次数。这样很容易做到

    void Test(ITrigger trigger, DateTimeOffset start, DateTimeOffset[] expectedFireTimes){
      var nextFire = startTime;
      foreach (var expectedFire in expectedFireTimes){
        nextFire = trigger.GetFireTimeAfter(nextFire);
        Assert.That(nextFire, Is.EqualTo(expectedFire));
      }
    }
    

    然而,我后来决定,我宁愿将测试结果视为一个单一的断言,而不是逐一断言元素,这样,如果前两次射击是正确的,但第三次射击是错误的,测试结果就会清楚地显示出预期的结果和发现的结果。这可以通过创建一个列表而不是在循环中断言来实现:

    void Test(ITrigger trigger, DateTimeOffset start, DateTimeOffset[] expectedFireTimes){
      var nextFire = startTime;
      var upcomingFireTimes = new List<DateTimeOffset>();
      foreach (var expectedFire in expectedFireTimes){
        nextFire = trigger.GetFireTimeAfter(nextFire);
        upcomingFireTimes.Add(nextFire);
      }
      Assert.That(upcomingFireTimes, Is.EqualTo(expectedFireTimes));
    }
    

    这也行得通,但这让我开始思考是否可以通过Linq来实现。 Linq是否有方法创建一个列表,其中每个元素都是基于初始种子和前一个元素计算的? 我能想到的最接近的是 Aggregate() ,它接受一个种子和一个函数,但只返回一个值,我必须将单个元素存储在函数内的列表中,这使得它与 foreach 上面的循环:

    var upcomingFireTimes = new List<DateTimeOffset>();
    expectedFireTimes.Aggregate(
      startTime,
      (seed, _) => {
        var nextfire = trigger.GetFireTimeAfter(seed);
        upcomingFireTimes.Add(nextFire);
        return nextFire;
      });
    

    我的目标是一个单行Linq方法,而不是最终只返回 最后的 计算值,如 聚合() 做,返回 全部的 沿途计算的值,如下所示:

    var upcomingFireTimes = expectedFireTimes.SomeLinqMethod(
      startTime,
      (seed, _) => trigger.GetFireTimeAfter(seed));
    
    1 回复  |  直到 1 月前
        1
  •  0
  •   rotabor    1 月前

    你的Linq方法是Select!

    DateTime firetime = startTime;
    var upcomingFireTimes = expectedFireTimes.Select(s => { return fireTime = trigger.GetFireTimeAfter(fireTime) } );
    

    您可以使用/不使用源集合生成所需的任何内容。