最佳实践在2个日期/ 2个周期之间总结算法

时间:2011-10-31 08:33:57

标签: c# linq

[已编辑并添加了一些其他相关信息]

我想知道你对这个场景的最佳处理。我想要一个“最后/第一个”之间的差异,而不是迭代每个值(或通过groupby进行求和)。值得一提的是,丢失的字段(下面的示例)首先是动态添加的(但仍然会将其外观视为“缺失”。

样品, 这里的范围包括日期(但可以是月,分,小时)。

获取范围内每个步骤之间的值之和。
获取数据以计算:

<missing>
2011-01-02  4.5 user1
2011-01-02  1.5 user2
2011-01-03  4.7 user1
2011-01-03  1.6 user2
2011-01-04  4.9 user1
2011-01-04  1.7 user2
2011-01-05  6.1 user1
2011-01-05  1.8 user2
<missing>
2011-01-06  1.9 user2
2011-01-07  6.5 user1
2011-01-07  2.0 user2
2011-01-08  6.9 user1
2011-01-08  2.1 user2
2011-01-09  7.0 user1
2011-01-09  2.2 user2
<missing>
<missing> ..

此表中的值按累计顺序排列。这意味着它们会像计时器一样增加几次启动/停止,但永远不会重新启动。


如果询问范围get 20110101--20110131",则方法回答"2011-01-01 3,2"

如果询问了get 20110107的确切时间段,则该方法将回答"2011-01-07 0.5"。结果为0.5,因为20110708 user1 6.9减去20110707 user1 6.5 == 0.4和20110708 user2 2.1减去20110707 user2 2.0 == 0.1。然后将0.4 + 0.1加在一起。

当我想返回一组计算的last / first值时会出现问题。如果我想在给定范围20110101--20110131中的每一天之间求和,那么"sum between last/first value"是否应该在该范围内的每一天执行。

结果如此

2011-01-02  0.3
2011-01-03  0.3
2011-01-04  1.3
2011-01-05  0
2011-01-06  0.1
2011-01-07  0.5
2011-01-08  0.2
2011-01-09  0
2011-01-10  0
2011-01-11  0 ..


该范围内的缺失期(天)将导致结果为零。我的意思是,20110104--20110105之间的总和不能为零(由于缺失值)。但是,如果您在20110104-20110107之间取得总和,则无法识别其间的缺失值。

1 个答案:

答案 0 :(得分:0)

Okey,它已经解决了,但它并不是真正的单一解决方案......

一些psudocode,

ConsumptionOfRange(List someList, Enum somePeriod)
{
  foreach (var user in someList.groupBy(d=>d.Name)
  {
      MethodToFillGapsInRange(ref someList)

      foreach (var period in someList.GroupBy(d => d.Date.Date))
      {
         // Kind of magic here. Ticks is the "weight" of the period somePeriod.
         // This make query know where in future to look for next valid value.
         var localValues = 
                 (from mv in someList
                  where mv.Date == period.Key 
                  || mv.Date.Date == period.Key.AddTicks(Method(somePeriod).Ticks)
                     select mv).ToList();

         // At this place, call the generic function used to calculate range.
         result.Add(ConsumptionRange(dc));
      }
  }   
}

//That generic function looks like this.
//Called directly calculating differences between big ranges (1000 or a million of records)
public AClass ConsumptionOfRange(List someValues)
{
   AClass grouped = 
        (from d in someValues.OrderBy(d=>d.Date)
         group d by d.Name into gr
         select new VC
         {
            Name = gr.FirstOrDefault().Name,
            Date = gr.FirstOrDefault().Date,

            Value =
              (gr.LastOrDefault().Value
                - gr.FirstOrDefault().Value)
               }).FirstOrDefault();

    return grouped;
}

答案可能对另一个人的帮助不大,但也许某些语义可以为此Q的后来访问者重复使用。或者我可以学习另一课来更好地做到这一点。