Ios 按时间间隔筛选数组

Ios 按时间间隔筛选数组,ios,arrays,swift,filtering,Ios,Arrays,Swift,Filtering,在我的应用程序中,我每20毫秒记录一次从设备加速计获取的加速度数据。我有一个名为AccelerationData的类来存储这些值。我还以毫秒为单位记录每次读取的时间戳 class AccelerationData { var timestamp: Int64 = 0 // in milliseconds var x: Double = 0.0 var y: Double = 0.0 var z: Double = 0.0 var timestampDat

在我的应用程序中,我每20毫秒记录一次从设备加速计获取的加速度数据。我有一个名为
AccelerationData
的类来存储这些值。我还以毫秒为单位记录每次读取的时间戳

class AccelerationData {
    var timestamp: Int64 = 0 // in milliseconds
    var x: Double = 0.0
    var y: Double = 0.0
    var z: Double = 0.0

    var timestampDate: Date {
        return Date(milliseconds: timestamp)
    }

    var JSONDictionary: [String: Any] {
        let jsonDictionary: [String: Any] = [
            "X": x,
            "Y": y,
            "Z": z,
            "TIME": timestamp
        ]
        return jsonDictionary
    }
}

extension Date {

    var milliseconds: Int64 {
        return Int64(self.timeIntervalSince1970 * 1000)
    }

    init(milliseconds: Int64) {
        self = Date(timeIntervalSince1970: TimeInterval(milliseconds / 1000))
    }

}
录音结束后,我需要创建一个包含所有这些读数的JSON主体。我希望通过每500毫秒(0.5秒)发生的读数对其进行过滤,而不是获取所有这些读数

根据我的研究,你可以使用
flatMap
来完成这样的任务,但我不确定在涉及时间戳等动态值时如何应用它


我希望能得到一些关于如何开始这方面的指导

为此,我将使用一个简单的for循环。 假设数据是按时间戳排序的,它可能如下所示:

let measurements: [AccelerationData] = ... // your full array of acceleration data
var reducedMeasurements = [AccelerationData]()

var nextTimeStamp = measurements.first!.timestamp // Assuming that the array is not empty
for accData in measurements {
    if accData.timestamp >= nextTimeStamp {
        reducedMeasurements.append(accData)
        nextTimeStamp += 500 // add 0.5 seconds
    }
}
如果您“坚持”使用过滤器,以下是一个可能的解决方案:

func timeFilter(delta: Int64) -> (Int64) -> Bool {
    var nextTimeStamp: Int64?
    return { timeStamp in
        if let next = nextTimeStamp {
            if timeStamp >= next {
                nextTimeStamp = next + delta
                return true
            } else {
                return false
            }
        } else {
            // First call:
            nextTimeStamp = timeStamp + delta
            return true
        }
    }
}

let measurements: [AccelerationData] = ...
let filter = timeFilter(delta: 500)
let reducedMeasurements = measurements.filter { filter($0.timestamp) }
timeFilter(delta:500)
创建一个使用捕获的 变量来跟踪下一个时间戳。代码可能会
可以简化,但希望能证明这一点。

注意,
日期(timeIntervalSince1970:)
以秒为单位,而不是以毫秒为单位。@MartinR哦,是的!实际上,我有一个单独的扩展方法来实现这一点。我忘了在课堂上更新属性。更新我的代码。按读数过滤“每500毫秒”?如果两次读取之间间隔2秒会发生什么?nextTimeStamp是一个日期,不是吗?@Guig:OP将属性定义为
var timestamp:Int64=0//(以毫秒为单位)
@MartinR-您需要在
timeFilter()函数中进行小的编辑。。。第一次
timeStamp>=nextTimeStamp
,如果nextTimeStamp==Int64.min{nextTimeStamp=timeStamp}
,则需要使用
更新nextTimeStamp。。。否则的话,你只需要通过…@DonMag:真的!这再次表明,应该使用选项,而不是“神奇常数”。希望它现在是正确的!