#[derive(Debug, PartialEq)]
struct AreaCodeIndex {
code: String,
childs: Vec<AreaCodeIndex>,
}
fn main() {
let code_str = vec![vec!["aa", "bb"], vec!["aa", "cc"]];
let mut code_area_data: Vec<AreaCodeIndex> = vec![];
for tmp in code_str {
let mut pe_ref = &mut code_area_data; //默认指向 code_area_data
for tt in tmp {
pe_ref = if let Some(i) = pe_ref.iter().position(|tc| tc.code == *tt) {
&mut pe_ref[i].childs
} else {
pe_ref.push(AreaCodeIndex {
code: tt.to_owned(),
childs: vec![],
});
&mut pe_ref.last_mut().unwrap().childs
};
}
}
println!("{:?}", code_area_data);
}
Without more context about what you are trying to achieve, it will be improbable that we will be able to help you effectively. None of us can read minds (I assume).
Given your snippet and the comment with the structure you want to create, how about using HashMap
s instead of Vec
s? The algorithm for what I think you want to create (your test case is very generic and again lacks any explanation) becomes a lot simpler and more effective with a data structure that does not require iteration for doing lookups and insertions. So here my solution, though again I have to emphasize the lack of information you provided:
use std::collections::HashMap;
#[derive(Debug, PartialEq)]
struct AreaCodeIndex {
code: String,
childs: HashMap<String, AreaCodeIndex>,
}
fn main() {
let code_str = vec![vec!["aa", "bb"], vec!["aa", "cc"]];
let mut code_area_data: HashMap<String, AreaCodeIndex> = HashMap::new();
for pair in code_str {
let key = pair[0];
let value = pair[1];
code_area_data
.entry(key.to_owned())
.and_modify(|index| {
index
.childs
.entry(value.to_owned())
.or_insert(AreaCodeIndex {
code: value.to_owned(),
childs: HashMap::new(),
});
})
.or_insert(AreaCodeIndex {
code: key.to_owned(),
childs: HashMap::from_iter([(
value.to_owned(),
AreaCodeIndex {
code: value.to_owned(),
childs: HashMap::new(),
},
)]),
});
}
assert_eq!(
code_area_data,
HashMap::from_iter([(
"aa".to_owned(),
AreaCodeIndex {
code: "aa".to_owned(),
childs: HashMap::from_iter([
(
"bb".to_owned(),
AreaCodeIndex {
code: "bb".to_owned(),
childs: HashMap::new(),
}
),
(
"cc".to_owned(),
AreaCodeIndex {
code: "cc".to_owned(),
childs: HashMap::new(),
}
)
])
}
)])
);
}
I expect code_area_data the result to be:
AreaCodeIndex {
code: "aa".to_string(),
childs: vec![
AreaCodeIndex {
code: "bb".to_string(),
childs: vec![],
},
AreaCodeIndex {
code: "bb".to_string(),
childs: vec![],
},
],
}
code_str has a lot of data, for the example I just wrote a part of it.
Since code_str has a large amount of data, need to use traversal
for tmp in code_str.iter_mut() {
while ... { ...}
}