json - 如何通过属性将 JSON 对象数组整理成包含每个对象属性向量的结构?

标签 json vector struct rust serde

我正在接收传感器数据流,我需要汇总这些数据并对其执行基本统计(平均值、最大值、最小值等)。有多个值,但传感器数据可能不一致,并且某些值可能会丢失。

从阅读本书来看,当 luminositycolor 的值丢失时,似乎应该使用 Option 但我很困惑这个。

这是我的传感器数据的示例:

[
    {
        "sensor": "left",
        "luminosity": "50",
        "color": "(255,0,0)"
    },
    {
        "sensor": "left",
        "color": "#0f0"
    },
    {
        "sensor": "right",
        "luminosity": "20"
    },
    {
        "sensor": "right",
        "luminosity": "40",
        "color": "(255,0,0)"
    },
    {
        "sensor": "left",
        "luminosity": "30"
    },
    {
        "sensor": "top",
        "luminosity": "10"
    },
    {
        "sensor": "right",
        "color": "(0,0,0)"
    }
]

每个传感器的数据将存储在以下结构的实例中:

struct Data {
    pub luminosity: Vec<String>,
    pub color: Vec<String>,
}

我想迭代上面的 JSON 对象,将传感器与正确的结构实例匹配(“正确的”传感器与“正确的”传感器结构)并将每个 JSON 观察的内容推送到向量上(在每个结构实例中).

需要记录缺失值,以便对于每个“观察”,对应传感器的结构实例的结构中的每个向量都有一个推送操作。

最佳答案

像这样的东西应该可以工作。它使用 Serde将每个 JSON 数组元素读入具有所需传感器名称的辅助结构 String , 和 Option<String>传感器每个值的数据。然后它遍历这些读数并将它们插入到 map 中,其中键是传感器名称,值是每个传感器值的数据向量。


#[macro_use]
extern crate serde_derive;

extern crate serde;
extern crate serde_json;

use std::collections::BTreeMap as Map;
use std::error::Error;

#[derive(Debug, Default)]
struct Data {
    luminosity: Vec<Option<String>>,
    color: Vec<Option<String>>,
}

fn main() {
    let input = r##"[
                      {
                        "sensor": "left",
                        "luminosity": "50",
                        "color": "(255,0,0)"
                      },
                      {
                        "sensor": "left",
                        "color": "#0f0"
                      },
                      {
                        "sensor": "right",
                        "luminosity": "20"
                      },
                      {
                        "sensor": "right",
                        "luminosity": "40",
                        "color": "(255,0,0)"
                      },
                      {
                        "sensor": "left",
                        "luminosity": "30"
                      },
                      {
                        "sensor": "top",
                        "luminosity": "10"
                      },
                      {
                        "sensor": "right",
                        "color": "(0,0,0)"
                      }
                    ]"##;
    let m = read_sensor_data(input).unwrap();
    println!("{:#?}", m);
}

fn read_sensor_data(input: &str) -> Result<Map<String, Data>, Box<Error>> {
    // Private helper struct that matches the format of the raw JSON
    #[derive(Deserialize)]
    struct RawReading {
        sensor: String,
        luminosity: Option<String>,
        color: Option<String>,
    }

    // Deserialize the raw data
    let raw_readings: Vec<RawReading> = serde_json::from_str(input)?;

    // Loop over raw data and insert each reading into the right sensor's struct
    let mut m = Map::new();
    for raw in raw_readings {
        // Look up this sensor's Data struct
        let sensor = m.entry(raw.sensor).or_insert_with(Data::default);

        // One push for every vector in the struct, even for missing observations
        sensor.luminosity.push(raw.luminosity);
        sensor.color.push(raw.color);
    }
    Ok(m)
}

关于json - 如何通过属性将 JSON 对象数组整理成包含每个对象属性向量的结构?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47245397/

相关文章:

json - 如何将嵌套的 JSON 解析为 Go 中的结构?

java - 从 URL 检索 JSON 时,Android Bad Request IOException

c++ - vector 循环无法正常运行

c - 使用函数将文本文件读入结构数组

c++ - 无序映射与 vector

c++ - std::vector 如何支持未知大小的自定义对象的连续内存

methods - 在函数内部定义结构的方法

json - 如何从 Auto Scaling 组获取私有(private) IP 地址

java - 使用 Jackson 反序列化 2D Json 数组时抛出错误

java - 使用jackson将Json对象转换为java对象