【问题标题】:Slicing array based on date condition基于日期条件的切片数组
【发布时间】:2017-11-05 18:56:54
【问题描述】:

我有一个带有Date 属性的对象数组。该数组按日期降序排序,即索引 0 处的元素是最新的,最后一个元素是最旧的。例如:Array[0] = 2017-11-05Array[1] = 2017-11-04

从这个数组中,我想创建一个包含数组的数组,其中包含基于截止日期是一个月中的哪一天的对象。例如,如果截止日期是每个月的第 6 天:

Array = [2017-11-07, 
         2017-11-06, 
         2017-11-05, 
         2017-11-04]

应该产生

NewArray = [[2017-11-07, 
             2017-11-06], 
            [2017-11-05, 
             2017-11-04]]

我已经根据我能想到的所有不同场景编写了我的算法(我不会在这里发布它,因为它很长而且充满了if and else 语句)。例如,如果列表中的两个相邻元素在同一个月份,我检查第一个元素 day 是否 >= 结束日期,第二个元素 day 是否

当我用边缘情况测试我的算法时,我完全被困住了。随着我继续前进,我想出了越来越多的边缘情况,if and else 语句的数量似乎趋于无穷大。是否有不同的方法来解决这个问题,因为如果没有大量 if and else 条件,我无法弄清楚如何编写算法。

编辑: 更成问题的案例。

Array = [2018-01-06, 
         2017-12-07, 
         2017-12-05, 
         2017-12-04,
         2017-11-16,
         2017-11-05,
         2017-09-27,
         2017-02-08,
         2016-12-07]

如果截止日期是 6 日,则所需的输出:

NewArray = [[2018-01-06], 
            [2017-12-07], 
            [2017-12-05, 
             2017-12-04,
             2017-11-16],
            [2017-11-05],
            [2017-09-27],
            [2017-02-08],
            [2016-12-07]]

例如,这种情况需要算法开始一个新的列表,其中月差 >= 2。在月差为 1 的情况下,即相隔一个月,它必须检查元素之一是否为 day是 >= 结束日期(并且)其他元素日是 = 结束日期,而其他元素的日期是否

【问题讨论】:

  • 您能否通过将其添加到您的示例中来澄清样本之间存在不同月/年差距的案例?
  • 这听起来很简单,你展示的数据集也很简单。你能展示一个更有问题的数据集吗?
  • @Larme 用一个更有问题的案例更新了帖子。
  • @matt 用一个更有问题的案例更新了帖子。
  • 也许我只是太密集了。您的第二个数据集的期望输出是什么?不就是一个财政年度内的每个日期都进入同一个子数组吗?这个问题与与什么相邻的东西无关。您只需查看我们是否处于我们已经在的同一财政年度。使用日期间隔,这很容易。如果没有,你能显示所需的输出吗?也许我不明白这个问题。

标签: arrays swift algorithm date slice


【解决方案1】:

如果我正确理解您的问题,Calendar 方法

是您正在寻找的。它允许您计算第 6 天 在给定日期之前发生的月份。然后比较每个 下一个当前截止日期的日期,并附加 它到当前切片,或者开始一个新切片并计算下一个 (即之前的时间)截止日期:

let yourDates: [Date] = ... // Your array of dates (in descending order)

let matchComponents = DateComponents(day: 6)
let cal = Calendar.current

var nextClosingDate = Date.distantFuture // So that the first date will start a new slice
var slicedDates: [[Date]] = []

for date in yourDates {
    if date >= nextClosingDate {
        // Append to current slice:
        slicedDates[slicedDates.count - 1].append(date)
    } else {
        // Start new slice and compute next closing date:
        slicedDates.append([date])
        nextClosingDate = cal.nextDate(after: date,
                                       matching: matchComponents,
                                       matchingPolicy: .nextTime,
                                       direction: .backward)!
    }
}

【讨论】:

  • 是的,但我建议使用DateInterval。可能更简单。
  • 这行得通。现在我必须了解它为什么起作用,但那是另一个故事。谢谢,我知道必须有另一种方法来代替我那充满条件的又长又丑又乱的代码。这太容易了..祝你有美好的一天!
  • Dictionary.init(grouping:by:) 似乎也是一种非常可行的方法来解决这个问题
  • @Alexander 你能详细说明如何实现吗?
  • @BartekSpitza 从每个日期中减去截止日期,然后按生成日期的月份分组。如果你想要一个像你所拥有的那样的二维数组,那么你可以dict.values.flatmap{$0}
猜你喜欢
  • 2015-07-19
  • 1970-01-01
  • 2018-09-20
  • 2021-03-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-04-17
  • 1970-01-01
相关资源
最近更新 更多