我最近接触了 Rust,之前是 Python 背景。我还在努力掌握函数式编程,因此我正在寻找关于编写 Rust 惯用方法的见解/反馈。
在下面的示例中,我有一个Parent
元素和Child
元素的列表,并希望根据id
将Child
元素排序到它们各自的父元素中。
在 Python 中,我会嵌套两个 for 循环,执行测试并相应地继续。但我不确定是否有更好/更高效/惯用的方法来做到这一点。
我已经标记了相关代码部分。当然,任何反馈都很好!
这里是一个可工作的 playgound: https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=233cfa5b5798090fa969ba348a479b1c
#[derive(Debug)]
struct Parent {
id: String,
children: Vec<Child>,
}
impl Parent {
pub fn from_id(id: String) -> Self {
Self {
id,
children: Vec::new(),
}
}
}
#[derive(Debug)]
struct Child {
parent_id: String,
}
impl Child {
pub fn from_parent_id(parent_id: String) -> Self {
Self { parent_id }
}
}
fn main() {
let mut parents: Vec<Parent> = vec!["a", "b", "c"]
.iter()
.map(|s| s.to_string())
.map(Parent::from_id)
.collect();
let mut children: Vec<Child> = vec!["a", "a", "b", "c", "c", "c"]
.iter()
.map(|s| s.to_string())
.map(Child::from_parent_id)
.collect();
// Is there a better way to do this?
while let Some(child) = children.pop() {
for parent in parents.iter_mut() {
if child.parent_id == parent.id {
parent.children.push(child);
break;
}
}
}
dbg!(parents);
dbg!(children);
}
Vec
吗?将整个父子关系作为HashMap<String,Vec<Child>>
或类似的东西处理更为自然。这样您就不必每次迭代父向量以找到具有正确ID的向量。 - cadolphsVec
,然后根据id
将它们混合在一起。此外,实际的Parent
和Child
结构体是更复杂的类型,具有其他字段,稍后将使用serde
进行序列化。 - tnahschildren
,像这样,这允许children
不是mut
。然后你可以使用find()
和map()
来使它 更加函数化。你可以将外部的for
循环转换为children.into_iter().for_each(|child| ...)
,但这似乎并没有提高可读性。 - user4815162342O(n*m)
- 如果这些数字很大,它可能会崩溃。创建父向量的 id->位置 的临时映射可以将其变为O(n+m)
,如 此示例 所示。 - user4815162342Parent
的实例超过1000个,但Child
的实例肯定会超过。我不确定周围代码的当前实现有多灵活,但临时映射是个好主意,特别是如果我找不到解决方法。让我看看我能用这个做些什么! - tnahs