i have been wondering how to solve the following problem.
you have a JSON like this and you parse using serde.
{
"student_name": "this guy",
"subjects": [{"Chemistry": 0},
{"Politics": 0},
{"Biology": 0},
{"Art": 0}],
}
then use a struct to map the types
struct Environment {
student_name: String,
subjects: Vec<HashMap<String, i32>>,
}
but when you try to loop over the keys from the subjects Vector you get all kinds of nasty errors like this one
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 `(_, _)`
this is all the code, i would really be greatful of someone helping me out. i really lost all hope; thank you beforehand.
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();
}
CodePudding user response:
You collection is of type Vec<HashMap<String, i32>>
, so you are given references to HashMap<String, i32>
when iterating, you can flat_map
over those as iterators also to actually get what you need:
for (key, val) in json.subjects.iter().flat_map(|d| d.iter()) {
println!("{}", key);
println!("----------------------");
}
CodePudding user response:
A subject
is a <HashMap<String, i32>
. Try iterating through every 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(())
}
Or, better yet, you can "forget" about loops altogether:
json.subjects
.iter()
.flat_map(|s| s.iter())
.for_each(|(key, value)| {
println!("{key}: {value}");
println!("----------------------");
});