尝试遍历 JSON 个键

Trying to loop over JSON keys

我一直在想如何解决下面的问题

你有一个像这样的 JSON 并且你使用 serde 进行解析。

{
    "student_name": "this guy",
    "subjects": [{"Chemistry": 0},
                {"Politics": 0},
                {"Biology": 0},
                {"Art": 0}],
}

然后使用结构来映射类型

struct Environment {
    student_name: String,
    subjects: Vec<HashMap<String, i32>>,
}

但是当你尝试从 subjects Vector 你会遇到像这样的各种讨厌的错误

error[E0308]: mismatched types
  --> src/main.rs:15:9
   |
15 |     for (key, val) in json.subjects.iter() {
   |         ^^^^^^^^^^    -------------------- this expression has type std::option::Option<&HashMap<std::string::String, i32>>`
   |         |
   |         expected struct `HashMap`, found tuple
   |
note: expected struct `HashMap<std::string::String, i32>`
               found tuple `(_, _)`

这就是所有代码,如果有人帮助我,我将不胜感激。我真的失去了所有的希望;预先谢谢你。

use serde_derive::Deserialize;
use serde_json::Result;
use std::{collections::HashMap, fs};

#[derive(Deserialize, Clone)]
struct Environment {
    student_name: String,
    subjects: Vec<HashMap<String, i32>>
}

fn data_parser() -> Result<()> {
    let data = fs::read_to_string("./src/data.json").unwrap();
    let json = serde_json::from_str::<Environment>(&data)?;
    for (key, val) in json.subjects.iter() {
        println!("{}", key);
        println!("----------------------");
    }
    Ok(())
}

fn main() {
    data_parser();
}

一个subject是一个<HashMap<String, i32>。尝试遍历每个 subject.

fn data_parser() -> Result<()> {
    let data = fs::read_to_string("./src/data.json").unwrap();
    let json = serde_json::from_str::<Environment>(&data)?;
    for subject in json.subjects.iter() {
        for (_key, value) in subject {
            println!("{}", value);
            println!("----------------------");
        }
    }
    Ok(())
}

或者,更好的是,您可以完全“忘记”循环:

 json.subjects
        .iter()
        .flat_map(|s| s.iter())
        .for_each(|(key, value)| {
            println!("{key}: {value}");
            println!("----------------------");
        });

你的集合是 Vec<HashMap<String, i32>> 类型的,所以你在迭代时得到了对 HashMap<String, i32> 的引用,你可以 flat_map 作为迭代器来实际获得你需要的东西:

for (key, val) in json.subjects.iter().flat_map(|d| d.iter()) {
    println!("{}", key);
    println!("----------------------");
}

Playground