【问题标题】:Return next value in array if Condition is true如果条件为真,则返回数组中的下一个值
【发布时间】:2016-03-21 13:52:09
【问题描述】:

我有一个 DateTimes 数组:

public DateTime GetNextGame()
{
    DateTime[] dateTimes = new DateTime[]
    {
        new DateTime(2016, 4, 11, 7, 5, 0),
        new DateTime(2016, 4, 12, 7, 5, 0),
        new DateTime(2016, 4, 13, 7, 5, 0),
        new DateTime(2016, 5, 30, 7, 5, 0),
        new DateTime(2016, 5, 31, 7, 5, 0),
        new DateTime(2016, 6, 1, 7, 5, 0),
        new DateTime(2016, 6, 2, 7, 5, 0),
        new DateTime(2016, 6, 14, 7, 5, 0),
        new DateTime(2016, 6, 15, 7, 5, 0),
        new DateTime(2016, 6, 16, 7, 5, 0),
        new DateTime(2016, 8, 16, 7, 5, 0),
        new DateTime(2016, 8, 17, 7, 5, 0),
        new DateTime(2016, 9, 12, 7, 5, 0),
        new DateTime(2016, 9, 13, 7, 5, 0),
        new DateTime(2016, 9, 14, 7, 5, 0),
        new DateTime(2016, 9, 19, 7, 5, 0),
        new DateTime(2016, 9, 20, 7, 5, 0),
        new DateTime(2016, 9, 21, 7, 5, 0),
        new DateTime(2016, 9, 22, 7, 5, 0)
    };

我的问题是.. 如果当前值不满足条件,我如何返回数组中的下一个值?我对此做了一些研究,发现了一个类似的问题,但它是在我不明白的 PHP 中。

所以我有一个循环遍历数组,然后是条件语句:

foreach(DateTime date in dateTimes)
{
    if(date.TimeOfDay < DateTime.Today.TimeOfDay)
    {
        return //next value in array?
    }
}

还试图返回日期 .ToShortDateString 以及 .ToShortTimeString 以供我查看。

我希望它看起来像这样。“下一场比赛是 3 月 3 日星期一晚上 7:05”

感谢任何帮助。

【问题讨论】:

  • 您可以使用for 代替foreachfor(int i = 0; i &lt; dateTimes.Length; i++) { date = dateTimes[i] ... }
  • 你可以保留counter来获取下一个值,但是为什么你不使用for
  • 对于这种问题,使用普通的for循环并手动索引数组可能更容易。然后只需使用index + 1(并进行适当的异常处理)。
  • 怎么知道下一个值会满足条件?你真的要退货吗?也许你应该使用return dateTimes.First(...)
  • 是的,如果您希望确保以正确的顺序前进,我会使用普通的 for 循环。并且只需根据数组中的每个条目编写一个为您进行检查的方法。

标签: c# arrays asp.net-mvc loops


【解决方案1】:

可以使用 Linq SkipWhile 运算符:

            DateTime firstValid = dateTimes.SkipWhile(d => d.TimeOfDay < DateTime.Today.TimeOfDay).First();

编辑:只是想提一下,我们假设数组已经按升序排序。

【讨论】:

  • 或添加OrderBy 子句。
  • 嗯,我不知道数据是否可以修改,所以我明确表示我们根据原始数据提供了答案。
  • 嗯,当然,我明白你为什么添加它:) 但是如果数据 是无序的,可以添加一个OrderBy 以便对其进行排序。我认为这将是几乎相同数量的文本,它会提供更多信息,而不是仅仅否认这个问题。
【解决方案2】:

如果您需要访问下一个(或上一个)项目,您应该使用for-loop:

for(int i = 0; i < dateTimes.Length - 1; i++)
{
    (dateTimes[i].TimeOfDay < DateTime.Today.TimeOfDay)
    {
        return dateTimes[i + 1];
    }
}

除此之外,你的比较毫无意义:

if(date.TimeOfDay < DateTime.Today.TimeOfDay)
{
    // this will never be true
}

DateTime.TimeOfDay 返回DateTimeTimeSpan,因此是时间分量。 DateTime.Today 返回今天的午夜,所以它是 TimeOfDay 将是 TimeSpan.Zero。这就是为什么date.TimeOfDay &lt; DateTime.Today.TimeOfDay 永远不会是真的。

我假设您想要日期早于今天的第一个DateTime。然后使用这个:

if(date.Date < DateTime.Today)
{
    // ...
}

【讨论】:

    【解决方案3】:

    尝试使用for 循环而不是foreach

    for (int i = 0; i < dateTimes.Length; ++i) {
      DateTime date = dateTimes[i];
    
      if (date.TimeOfDay < DateTime.Today.TimeOfDay) {
        if (i < dateTimes.Length - 1) // not the last item
          return date[i + 1];
        else {
          //TODO: there's no "next item" for the last one
        } 
      }
    }
    

    【讨论】:

      【解决方案4】:

      如果你因为某些原因不想使用for 循环,那么试试这个:

      int counter = 0;
      foreach(DateTime date in dateTimes)
      {
          if(date.TimeOfDay < DateTime.Today.TimeOfDay)
          {
              return dateTimes[counter + 1];
          }
          counter++;
      }
      

      【讨论】:

      • 这只是一个混淆的for 循环——你有初始化器、条件和迭代器。这怎么不是 for 循环? :)
      【解决方案5】:

      使用 for 循环代替 foreach。

      for(int i = 0; i < dateTimes.Length; i++)
      {
          if(dateTimes[i].TimeOfDay < DateTime.Today.TimeOfDay && i < dateTimes.Length - 1)
          {
              return dateTimes[i + 1];
          }
      }
      

      另请注意,您需要通过写入if(i &lt; dateTimes.Length) 来检查您是否超出了数组的范围。

      你也可以稍微组合一下循环条件:

      for(int i = 0; i < dateTimes.Length - 1; i++)
      {
          if(dateTimes[i].TimeOfDay < DateTime.Today.TimeOfDay)
          {
              return dateTimes[i + 1];
          }
      }
      

      【讨论】:

      • 你可以把这个限制i &lt; dateTimes.Length放在for声明中
      【解决方案6】:

      你可以试试:

      foreach(DateTime date in dateTimes)
      {
          if(!(date.TimeOfDay < DateTime.Today.TimeOfDay))
          {
              continue;
          }
          return date;
      }
      

      【讨论】:

        【解决方案7】:

        你可以这样做

        return dateTimes.OrderBy(dateTime => dateTime).FirstOrDefault(dateTime => dateTime > DateTime.Now);
        

        或者如果你想使用TodayTimeOfDay

        return dateTimes.OrderBy(dateTime => dateTime).FirstOrDefault(dateTime => dateTime.Date > DateTime.Today &&  dateTime.TimeOfDay > DateTime.Today.TimeOfDay);
        

        【讨论】:

        • 简短的工作答案。但是 OP 不想要 DateTime.Now 而是 DateTime.Today.TimeOfDay
        • @HimBromBeere 我添加了一个替代版本
        【解决方案8】:

        如果您事先知道您的数组已完全排序,请使用:

        var idx = Array.BinarySearch(dateTimes, DateTime.Now);
        
        return dateTimes[idx >= 0 ? idx : ~idx];
        

        像这里的许多其他解决方案一样,如果没有即将到来的“下一场比赛”,这将失败。如果应该更优雅地处理,请检查您是否在数组范围内。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2016-05-03
          • 2017-09-17
          • 2021-03-17
          • 2016-04-10
          • 2011-08-21
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多