我正在尝试从JSON数据创建一个花瓣图Graph。JSON包含图的边缘,键表示起始顶点,值是相邻顶点的列表。生成具有边向量的图是有可能的。
我设法创建了一个Vec<(String, String))>,但没有像预期的那样创建一个Vec<(&str, &str)>。
extern crate petgraph;
extern crate serde_json;
use petgraph::prelude::*;
use serde_json::{Value, Error};
fn main() {
let data = r#"{
"A": [ "B" ],
"B": [ "C", "D" ],
"D": [ "E", "F" ]
}"#;
let json_value: Value = serde_json::from_str(data).unwrap();
let mut edges: Vec<(String, String)> = vec![];
if let Value::Object(map) = json_value {
for (from_edge, array) in &map {
if let &Value::Array(ref array_value) = array {
for edge in array_value {
if let &Value::String(ref to_edge) = edge {
edges.push((from_edge.clone(), to_edge.clone()))
}
}
}
}
}
// let graph = DiGraphMap::<&str, ()>::from_edges(edges);
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected struct
// `std::string::String`, found &str
}我尝试了不同的东西:
DiGraphMap::<String, ()>,但是它不接受它。Vec<(String, String)>转换为Vec<(&str, &str)>。我读过这个职位,但没什么用。edges.push((&"a", &"b"))可以工作,但不能使用edges.push((&from.clone(), &to.clone()))。这里可能有更好的方法来提取边缘。
发布于 2018-03-03 22:39:44
将图形类型更改为
DiGraphMap::<String, ()>,但是它不接受它。
GraphMap要求节点类型是可复制的。String不实现Copy。
将
Vec<(String, String)>转换为Vec<(&str, &str)>
正如你在问题中所提到的,这是不可能的。您可以做的是使用&str创建第二个引用原始String的String:
let a: Vec<(String, String)> = vec![("a".into(), "b".into())];
let b: Vec<(&str, &str)> = a.iter()
.map(|&(ref x, ref y)| (x.as_str(), y.as_str()))
.collect();但是,在这种情况下不需要这样做。相反,将JSON数据读入对地图建模的数据结构(我选择了BTreeMap),并将String放在那里。然后,您可以构造一个迭代器,其中包含对这些Strings的引用,并根据它构建图:
extern crate petgraph;
extern crate serde_json;
use petgraph::prelude::*;
use std::collections::BTreeMap;
use std::iter;
fn main() {
let data = r#"{
"A": [ "B" ],
"B": [ "C", "D" ],
"D": [ "E", "F" ]
}"#;
let json_value: BTreeMap<String, Vec<String>> =
serde_json::from_str(data).unwrap();
let edges = json_value
.iter()
.flat_map(|(k, vs)| {
let vs = vs.iter().map(|v| v.as_str());
iter::repeat(k.as_str()).zip(vs)
});
let graph: DiGraphMap<_, ()> = edges.collect();
}我需要将它封装成一个函数
这几乎不可能做到。由于JSON字符串包含UTF-8数据,Serde允许您获取对原始输入字符串的引用。您需要记住,您的graph不能超过input。
fn main() {
let data = r#"{
"A": [ "B" ],
"B": [ "C", "D" ],
"D": [ "E", "F" ]
}"#;
let graph = example(data);
}
fn example(data: &str) -> serde_json::Result<DiGraphMap<&str, ()>> {
let json_value: BTreeMap<&str, Vec<&str>> = serde_json::from_str(data)?;
let edges = json_value
.into_iter()
.flat_map(|(k, vs)| iter::repeat(k).zip(vs));
Ok(edges.collect())
}https://stackoverflow.com/questions/49087693
复制相似问题