Reputation: 4232
test2.json
[
{"name":"Lucy","age":18,"achievement":[95,86.5,90]},
{"name":"Lily","age":19,"achievement":[92.5,89,91]},
{"name":"Jack","age":20,"achievement":[93,90,93.5]}
]
main.rs
use std::fs::File;
use std::io::BufReader;
use serde_json::{Result as SResult, Value};
fn get_profile() -> SResult<Value> {
let file = File::open("test2.json").expect("file should open read only");
let reader = BufReader::new(file);
let mut v: Value = serde_json::from_reader(reader)?;
Ok(v.take())
}
fn main() {
let profiles = get_profile().unwrap();
for element in profiles.as_array().iter() {
println!("the value is: {}", element["age"]);
}
}
error:
λ cargo run
Compiling hello-rust v0.1.0 (D:\workspace\rust-projects\hello-rust)
error[E0277]: the type `[Value]` cannot be indexed by `&str`
--> src\main.rs:20:38
|
20 | println!("the value is: {}", element["age"]);
| ^^^^^^^^^^^^^^ slice indices are of type `usize` or ranges of `usize`
|
= help: the trait `SliceIndex<[Value]>` is not implemented for `&str`
= note: required because of the requirements on the impl of `std::ops::Index<&str>` for `Vec<Value>`
For more information about this error, try `rustc --explain E0277`.
error: could not compile `hello-rust` due to previous error
How to fix the issue? Any help please, thanks.
Upvotes: 0
Views: 219
Reputation: 2988
You are calling .iter()
on an Option<&Vec<Value>>
. The iterator yields one value if the Option is a Some, otherwise none.
You can change your loop to this instead, which will yield one Value
(here the object) at a time:
for element in profiles.as_array().unwrap().iter() {
println!("the value is: {}", element["age"]);
}
Note: I'd at least use is_array()
etc. to validate the structure and improve error handling (not just unwrap()
. You get a lot for free when using structs and Deserialize
instead of parsing everything manually.
Example:
#[derive(Deserialize)]
struct Profile {
name: String,
age: usize,
achievement: Vec<f64>,
}
let profiles: Vec<Profile> =
serde_json::from_reader(BufReader::new(File::open("test2.json").unwrap())).unwrap();
for profile in profiles {
println!("the value is: {}", profile.age);
}
Upvotes: 2