簡體   English   中英

從JSON數組中選擇鍵的子集

[英]Selecting a subset of keys from a JSON array

我正在嘗試解析一個JSON API,它吐出這樣的輸出:

{
  "message": "success", 
  "number": 6, 
  "people": [
    {
      "craft": "ISS", 
      "name": "Gennady Padalka"
    }, 
    {
      "craft": "ISS", 
      "name": "Mikhail Kornienko"
    }, 
    {
      "craft": "ISS", 
      "name": "Scott Kelly"
    }, 
    {
      "craft": "ISS", 
      "name": "Oleg Kononenko"
    }, 
    {
      "craft": "ISS", 
      "name": "Kimiya Yui"
    }, 
    {
      "craft": "ISS", 
      "name": "Kjell Lindgren"
    }
  ]
}

資料來源: http : //api.open-notify.org/astros.json

我為此使用了serde到目前為止 ,我們已經設法提出了以下代碼:

extern crate curl;
extern crate serde_json;

use curl::http;
use std::str;
use serde_json::{from_str};

fn main() {
    // Fetch the data
    let response = http::handle()
       .get("http://api.open-notify.org/astros.json")
       .exec().unwrap();

     // Get the raw UTF-8 bytes
     let raw_bytes = response.get_body();
     // Convert them to a &str
     let string_body: &str = str::from_utf8(&raw_bytes).unwrap();

     // Get the JSON into a 'Value' Rust type
     let json: serde_json::Value = serde_json::from_str(&string_body).unwrap();

     // Get the number of people in space
     let num_of_ppl: i64 = json.find_path(&["number"]).unwrap().as_i64().unwrap();
     println!("There are {} people on the ISS at the moment, they are: ", num_of_ppl);

     // Get the astronauts
     // Returns a 'Value' vector of people
     let ppl_value_space = json.find_path(&["people"]).unwrap();
     println!("{:?}", ppl_value_space);
}

現在, ppl_value_space像預期的那樣為我提供了此功能:

[{"craft":"ISS","name":"Gennady Padalka"}, {"craft":"ISS","name":"Mikhail Kornienko"}, {"craft":"ISS","name":"Scott Kelly"}, {"craft":"ISS","name":"Oleg Kononenko"}, {"craft":"ISS","name":"Kimiya Yui"}, {"craft":"ISS","name":"Kjell Lindgren"}]

但是,我想獲得"name"鍵,因為它本質上具有以下內容:

[{"name":"Gennady Padalka"}, {"name":"Mikhail Kornienko"}, {"name":"Scott Kelly"}, {"name":"Oleg Kononenko"}, {"name":"Kimiya Yui"}, {"name":"Kjell Lindgren"}]

為了能夠僅獲得當前太空中宇航員的名字。

我如何在"people"獲得"name" "people" ,而無需"craft"

試圖這樣name

ppl_value_space[0].find_path(&["name"]).unwrap();

但這以恐慌結尾,這基本上意味着鍵為None ,因為我將unwrap()Option<T>

這對我有用:

if let &Value::Array(ref people) = ppl_value_space {
    let names = people.iter().filter_map(|person| person.find_path(&["name"]));
    for name in names {
        println!("{:?}", name);
    }
}

由於serde_json::Value是一個enum ,它可以是許多不同類型的值。 數組只是其中之一,也可能是字符串或數字之類的其他東西。 我們期望它是一個數組,但是Rust迫使我們考慮其他情況。

在這種情況下,我們使用if-let語句忽略了Value::Array以外的所有類型。 當條件為真時,我們將引用包含的數組。

我們遍歷數組中的每個項目,並在其中找到名稱對象。 filter_map用於忽略None值,但是您可能需要做一些不同的事情。

每個值都已打印出來,但是您也可以collect它們collect到一個新的Vec或更令人興奮的東西中。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM