1

我正在使用 Chart JS 库创建折线图。我使用的数据来自两个不同的温度传感器(传感器 1 和传感器 2),它们可能不一定具有相同的时间戳。我想将数据分成 3 个数组:1. 传感器 1 读数 2. 传感器 2 读数 3. 时间戳

如果在特定时间步长没有值,那么对于另一个传感器的一个传感器,该数组应该有一个空白值,如该数组的索引 1:[0, ,1,2]

以下是数据示例:

zdata =
    { "data": [
        {
          "timestamp": 10,
          "sensor_id": 1,
          "temp": 14.5,
        },
        {
          "timestamp": 20,
          "sensor_id": 1,
          "temp": 18,
        },
        {
          "timestamp": 30,
          "sensor_id": 1,
          "temp": 25.5,
        },
        {
          "timestamp": 5,
          "sensor_id": 2,
          "temp": 24.5,
        },
        {
          "timestamp": 20,
          "sensor_id": 2,
          "temp": 29.5,
        }
      ]
    };

以及我希望数组的结果如何:

时间戳:[5,10,20,30]

传感器 1:[,14.5,18,25.5]

传感器 2:[24.5,,29.5,]

我还需要动态更改传感器的数量,因此,例如,数据可能包含 3 个传感器读数,我需要生成一个额外的数组。

到目前为止,我尝试了以下操作,但是,“result.temp”操作返回一个未定义的值,因此代码确实有效。

var unique_timestamps = [...new Set(zdata.data.map(item => item.timestamp))];
console.log(unique_timestamps);

var sensors = [...new Set(zdata.data.map(item => item.sensor_id))];
console.log(sensors);

// Will hold final arrays of sensor readings
var temperature_datasets = [];

for (i = 0; i < sensors.length; i++) {

    // Holds the array of temperatures for one sensor
    readings_arr =[];

    for (j = 0; j < unique_timestamps.length; j++) {

        var result = zdata.data.filter(obj => {
            return (obj.timestamp === unique_timestamps[j] && obj.sensor_id === sensors[i])
        })
        readings_arr[j]=result.temp;

    }

    temperature_datasets[i] = readings_arr

}

我有两个问题:

  1. 有没有更有效的方法来减少操作?
  2. 如果没有,为什么我会得到“result.temp”的未定义结果以及如何获得温度值。
4

1 回答 1

1

这是一个现代 ES6 版本,它可以获得相同的结果,并且希望更具可读性和性能。

代码被解释为注释。最初,我们使用时间戳作为键和传感器作为值来旋转一个对象。然后我们使用它来获取时间戳数组和传感器值数组,如图所示。

zdata =
    { "data": [
        {
          "timestamp": 10,
          "sensor_id": 1,
          "temp": 14.5,
        },
        {
          "timestamp": 20,
          "sensor_id": 1,
          "temp": 18,
        },
        {
          "timestamp": 30,
          "sensor_id": 1,
          "temp": 25.5,
        },
        {
          "timestamp": 5,
          "sensor_id": 2,
          "temp": 24.5,
        },
        {
          "timestamp": 20,
          "sensor_id": 2,
          "temp": 29.5,
        }
      ]
    };
    
 let {sensors ,...sensorTimeMap} = zdata.data.reduce((acc,val) => {
    if(!acc[val.timestamp]) 
       acc[val.timestamp] = {};
    acc[val.timestamp][val.sensor_id] = val.temp; // pivots the data against timestamp so as to give us more performant lookups later
    if(!acc.sensors.includes(val.sensor_id))
       acc.sensors.push(val.sensor_id)
    return acc;
 },{ sensors:[] }); // Since the number of sensors is dynamic and should be extracted from the data object, we collect available sensors in an array and also create a timeStampMap for future reference
 
 let timestamp = Object.keys(sensorTimeMap); // All timestamps of the pivot generated
 let sensorValArray = sensors.map(sensor => (Object.values(sensorTimeMap).map(obj => obj[sensor] || ''))); // gives us an array of arrays since we cannot know for sure how many sensors are there beforehand and cannot store in different variables. But this is the only way to handle dynamic length since we cannot know how many variables to declare beforehand!
 
 console.log(timestamp,sensorValArray);

于 2019-02-08T15:00:36.627 回答