【问题标题】:Values not updating in while loop在 while 循环中不更新值
【发布时间】:2018-08-14 15:20:16
【问题描述】:

我在 Visual Studios 2017 中创建了一个 wpf 应用程序。我目前正在尝试在日期时间的有序列表中查找最近的日期时间。看来我的“最近”值没有在循环中更新,但对我来说一切都是正确的。

这是我的代码

while (r < dataTable.Rows.Count)    //get nearest value to the current target
{
    long nearest = long.MaxValue;
    long dtDiff = 0;
    while(nearest > dtDiff)
    {
      DateTime dtCurr = Convert.ToDateTime(dataTable.Rows[r][dtCol].ToString());
      dtDiff = Math.Abs(dtTarget.Ticks - dtCurr.Ticks);
      if(dtDiff < nearest)
      {
          Debug.WriteLine("Smaller value found r:" + r);
          Debug.WriteLine("diff:" + dtDiff.ToString() + " nearest:" + nearest);
          nearest = dtDiff;
          r++;
       }
       else
       {
          Debug.WriteLine("nearest value found " + r);
          long v = long.Parse(dataTable.Rows[r][dtCol + 1].ToString());
          values.Add(new NormValue { datetime = dt, value = v});
          dtTarget.AddSeconds(inc);
          break;
        }
    }
}

在 if(dtDiff 语句中,应该更新 nearest 变量,但根据我的调试打印语句,它永远不会改变。我不确定我做错了什么。

编辑: 这是数据表的示例:

01-May-16 00:00:10

01-May-16 00:00:40

01-May-16 00:01:10

01-May-16 00:01:40

01-May-16 00:02:10

01-May-16 00:02:40

01-May-16 00:03:10

我的目标日期时间值递增,所以它会像

01-May-16 00:00:10

01-May-16 00:00:20

01-May-16 00:00:30

01-May-16 00:00:40

因此可以使用相同的值或完全跳过值

【问题讨论】:

  • 看起来很复杂! if(dtDiff &lt; nearest) 中的代码是否正在执行,即调试语句?您说您有一个列表,但实际上您有一个数据表 - 如果您有一个日期时间列表而不是需要检索和转换的数据表,这可能会更简单(如果没有其他内容,可以阅读)。
  • 是的,调试语句正在执行,这就是我发现 nearest 永远不会更新的原因。它永远不会进入 else 语句。是的,这是一个数据表,但我或多或少地将它视为一个列表。稍后我可能会按照您的建议将其更改为实际列表
  • @Jummi,好吧,它永远不会进入 else,因为你的差异总是小于 long.MaxValue 所以在阅读第一个日期后它总是会进入 if condition
  • @Bijan 我在帖子中添加了一个编辑,以向您展示我的数据是什么样的。所以在我的情况下,最接近的值不是下一个值。
  • 目标是否总是以固定值增加?

标签: c# while-loop


【解决方案1】:

第二个循环(while(nearest &gt; dtDiff))需要最接近的值大于 dtDiff,但是,在 if 语句(if(dtDiff &lt; nearest))中,程序设置与 dtDiff 值最接近。将while(nearest &gt; dtDiff)设置为while(nearest &gt;= dtDiff)即可解决问题。

【讨论】:

  • 是的...这就是我想要做的。唯一的问题是,尽管将 nearest 重新分配给 dtDiff 的值,它仍然是相同的值
  • 你确定程序进入if语句吗?还有一个问题。当您说“我的调试打印语句”时,Debug.WriteLine("diff:" + dtDiff.ToString() + " nearest:" + nearest); 是什么意思?
  • 是的,我输入了 Debug.WriteLine 语句
  • 它总是打印最接近的 long.MaxValue。在第一次“while(nearest > dtDiff)”迭代中,先打印值再设置值,所以打印的值为long.MaxValue。正如我的回应所说,第二次迭代永远不会发生,因为现在最接近于 dtDiff。
【解决方案2】:

"nearest" 由于外部循环而具有相同的值。每次程序转到外循环时,“最近”都会获得新值。尝试在循环外声明“最近”。

long nearest = long.MaxValue;
while (r < dataTable.Rows.Count)
{
    // Your code
}

【讨论】:

  • 我认为他实际上想在代码退出内部 while 循环时重置最接近的值
  • 如果程序只在内循环中进行一次,或者在外循环的最后一次迭代中没有进入内循环,那么他将在“最近”变量中获得“long.MaxValue”。 . .可能是这个问题
【解决方案3】:

我认为不需要第二个循环。你可以试试这个代码:

DateTime dtCurr = Convert.ToDateTime(dataTable.Rows[r][dtCol].ToString());
long nearest = dtCurr.Ticks - (dtCurr.Ticks % (System.TimeSpan.TicksPerSecond * inc));
//nearest += (System.TimeSpan.TicksPerSecond * inc);

它计算小于dtCurr.Ticks 的最接近的数字,步长等于inc 秒。取消注释最后一行给出下一个数字。

【讨论】:

  • 哦,好吧,我会试一试。谢谢!
【解决方案4】:

循环固定范围索引的标准方法是使用 for 循环。 nearest 的值必须在在循环之前初始化,否则它会一直被重置。

我不明白内部 while 循环的目的。一个循环就可以完成这项工作。另外,我不明白为什么dtTarget 在这个过程中会增加。

另一个问题是您的Debug.WriteLine 在分配nearest 值之前出现,因此您总是看到前一个。

long nearest = long.MaxValue;
for (int r = 0; r < dataTable.Rows.Count; r++) {
    DateTime dtCurr = Convert.ToDateTime(dataTable.Rows[r][dtCol].ToString());
    long dtDiff = Math.Abs(dtTarget.Ticks - dtCurr.Ticks);
    if (dtDiff < nearest) {
        nearest = dtDiff;
        Debug.WriteLine($"Smaller value found at: {r}");
        Debug.WriteLine($"diff:{dtDiff} nearest:{nearest}");
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-28
    • 1970-01-01
    • 2019-03-05
    • 2016-02-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多