javascript - 如何处理包含传感器读数和时间戳的对象数组,并验证传感器具有特定值的次数和时间?

标签 javascript node.js

我正在处理一些传感器数据,我的输入看起来像这样(值始终为 1 或 0,但值和时间戳数组的长度要长得多,因为它们包含传感器 24 小时的读数数据摄取每秒发生一次):

 const input=   {
  values: [ 0, 1, 0, 0, 1 ],
  timestamps: [
    '2022-08-19T08:01:21.000Z',
    '2022-08-19T08:01:22.000Z',
    '2022-08-19T08:01:23.000Z',
    '2022-08-19T08:01:24.000Z',
    '2022-08-19T08:01:25.000Z'
  ]
}

或者我可以轻松地将输入转换为以下格式(我无法决定哪种格式更合适):<​​/p>

 const input=  [{value: 0, timestamp: '2022-08-19T08:01:21.000Z'},
                {value: 1, timestamp: '2022-08-19T08:01:22.000Z'},
                {value: 0, timestamp: '2022-08-19T08:01:23.000Z'},
                {value: 0, timestamp: '2022-08-19T08:01:24.000Z'},
                {value: 1, timestamp: '2022-08-19T08:01:25.000Z'}]

我的目标是识别传感器读数为 0 时的所有周期,并验证这些周期是否短于或长于 1 分钟,即,对于上述情况,我希望得到以下结果:

result = [
    {startDate: '2022-08-19T08:01:21.000Z', endDate= '2022-08-19T08:01:22.000Z', isShorterThanOneMin: true},
    {startDate: '2022-08-19T08:01:23.000Z', endDate= '2022-08-19T08:01:25.000Z', isShorterThanOneMin: true}]

您能建议一种省时的方法来解决这个问题吗?

最佳答案

简单 JavaScript 版本

class Processor {
    constructor(inputs) {
        this.inputs = inputs;
        this.outputs = [];
        this.process();
    }
    process() {
        while (this.inputs.length > 0) {
            const input = this.inputs.shift();
            if (this.previousInput === undefined) {
                this.previousInput = input.value === 0 ? input : undefined;
                continue;
            }
            if (this.previousInput.value === 0) {
                if (input.value === 0)
                    continue;
                this.outputs.push({
                    startDate: this.previousInput.date,
                    endDate: input.date,
                    isShorterThanOneMinute: (input.date.getTime() - this.previousInput.date.getTime()) < 60000
                });
                this.previousInput = undefined;
            }
        }
    }
}
const inputs = [
    { value: 0, date: new Date("2022-08-19T08:01:21.000Z") },
    { value: 1, date: new Date("2022-08-19T08:01:22.000Z") },
    { value: 0, date: new Date("2022-08-19T08:01:23.000Z") },
    { value: 0, date: new Date("2022-08-19T08:01:24.000Z") },
    { value: 1, date: new Date("2022-08-19T08:01:25.000Z") }
];
const processor = new Processor(inputs);
console.log(processor.outputs);

更漂亮、更长的 TypeScript 版本

interface Input {
    value: number;
    date: Date;
}
namespace Input {
    export type List = Input[];
    export const clone = (input: Input): Input => {
        return {
            value: input.value,
            date: new Date(input.date.getTime())
        }
    }
}
interface Output {
    startDate: Date;
    endDate: Date;
    isShorterThanOneMinute: boolean;
}
namespace Output {
    export type List = Output[];
    export const clone = (output: Output): Output => {
        return {
            startDate: new Date(output.startDate.getTime()),
            endDate: new Date(output.endDate.getTime()),
            isShorterThanOneMinute: output.isShorterThanOneMinute
        }
    }
}
class Processor {
    private previousInput?: Input;
    private outputs: Output.List = [];
    private inputs: Input.List;
    constructor(inputs: Input.List) {
        this.inputs = inputs.map(Input.clone);
        this.process();
    }
    private process() {
        while (this.inputs.length > 0) {
            const input = this.inputs.shift()!;

            if (this.previousInput === undefined) {
                this.previousInput = input.value === 0 ? input : undefined;
                continue;
            }

            if (this.previousInput.value === 1) {
                throw new Error(`This is not possible, because we never store an input with value = 1.`);
            }

            if (input.value === 0) continue;

            this.outputs.push({
                startDate: this.previousInput.date,
                endDate: input.date,
                isShorterThanOneMinute: (input.date.getTime() - this.previousInput.date.getTime()) < 60000
            });

            this.previousInput = undefined;
        }
    }
    getOutputs(): Output.List {
        return this.outputs.map(Output.clone);
    }
    append(input: Input): this {
        this.inputs.push(Input.clone(input));
        this.process();
        return this;
    }
}

const inputs: Input.List = [
    { value: 0, date: new Date("2022-08-19T08:01:21.000Z") },
    { value: 1, date: new Date("2022-08-19T08:01:22.000Z") },
    { value: 0, date: new Date("2022-08-19T08:01:23.000Z") },
    { value: 0, date: new Date("2022-08-19T08:01:24.000Z") },
    { value: 1, date: new Date("2022-08-19T08:01:25.000Z") }
];

const processor = new Processor(inputs);
console.log(processor.getOutputs());

// Continue using the instance as more entries because available...
processor.append({ value: 1, date: new Date("2022-08-19T08:02:25.000Z") });
processor.append({ value: 1, date: new Date("2022-08-19T08:03:25.000Z") });
processor.append({ value: 0, date: new Date("2022-08-19T08:04:25.000Z") });
processor.append({ value: 0, date: new Date("2022-08-19T08:05:25.000Z") });
processor.append({ value: 0, date: new Date("2022-08-19T08:06:25.000Z") });
processor.append({ value: 1, date: new Date("2022-08-19T08:07:25.000Z") });
console.log(processor.getOutputs());

关于javascript - 如何处理包含传感器读数和时间戳的对象数组,并验证传感器具有特定值的次数和时间?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73426002/

相关文章:

mysql - 我需要帮助编写家谱的 MySQL INSERT 查询

javascript - 使用 pm2 查看当前目录外的文件

使用链接元素时未加载 JavaScript

javascript - socket.io 无法正常工作

javascript - 为什么 AngularJS 向服务器生成的输出添加额外的类?

node.js - Grunt-contrib-connect:如何在指定的浏览器中启动服务器

在 Parcel 构建期间在 HTML 文件中调用时不会触发 JavaScript 函数

javascript - 页面通过 HTTPS 加载,但请求不安全。我找不到它

Javascript/Jquery 在循环中获取位置很慢

javascript - 如何让 php `json_encode` 返回 Javascript 数组而不是 Javascript 对象?