Map on the data within the node instead of the node itself
This commit is contained in:
parent
0fbfb4f1ad
commit
c2e34db79c
|
@ -60,14 +60,23 @@ impl<T> Tree<T> {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Convert each node of a tree from type T to type U
|
||||||
pub fn map<F, U>(&self, op: F) -> Tree<U>
|
pub fn map<F, U>(&self, op: F) -> Tree<U>
|
||||||
where
|
where
|
||||||
F: FnOnce(&Node<T>) -> Node<U> + Copy,
|
F: FnOnce(&T) -> U + Copy,
|
||||||
{
|
{
|
||||||
|
// A key part of this is to avoid recursion. There is no telling how deep a tree may go (Go
|
||||||
|
// game records can go hundreds of nodes deep), so we're going to just avoid recursion.
|
||||||
match self {
|
match self {
|
||||||
Tree::Empty => Tree::Empty,
|
Tree::Empty => Tree::Empty,
|
||||||
Tree::Root(root) => {
|
Tree::Root(root) => {
|
||||||
let new_root = op(root);
|
let new_root = Node::new(op(&root.value()));
|
||||||
|
|
||||||
|
// This queue serves as a work list. Each node in the queue needs to be converted,
|
||||||
|
// and I've paired the node up with the one that it's supposed to be attached to.
|
||||||
|
// So, as we look at a node A, we make sure that all of its children gets added to
|
||||||
|
// the queue, and that the queue knows that the conversion of each child node
|
||||||
|
// should get attached to A.
|
||||||
let mut queue: VecDeque<(Node<T>, Node<U>)> = root
|
let mut queue: VecDeque<(Node<T>, Node<U>)> = root
|
||||||
.children()
|
.children()
|
||||||
.iter()
|
.iter()
|
||||||
|
@ -75,7 +84,7 @@ impl<T> Tree<T> {
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
while let Some((source, dest)) = queue.pop_front() {
|
while let Some((source, dest)) = queue.pop_front() {
|
||||||
let res = op(&source);
|
let res = Node::new(op(&source.value()));
|
||||||
dest.add_child_node(res.clone());
|
dest.add_child_node(res.clone());
|
||||||
|
|
||||||
for child in source.children().iter() {
|
for child in source.children().iter() {
|
||||||
|
@ -174,7 +183,7 @@ mod tests {
|
||||||
let n = n.add_child_value(16);
|
let n = n.add_child_value(16);
|
||||||
let _ = n.add_child_value(17);
|
let _ = n.add_child_value(17);
|
||||||
|
|
||||||
let tree2 = tree.map(|v| Node::new(v.value().to_string()));
|
let tree2 = tree.map(|v| v.to_string());
|
||||||
|
|
||||||
assert!(tree2.find_bfs(|val| *val == "15").is_some());
|
assert!(tree2.find_bfs(|val| *val == "15").is_some());
|
||||||
assert!(tree2.find_bfs(|val| *val == "16").is_some());
|
assert!(tree2.find_bfs(|val| *val == "16").is_some());
|
||||||
|
|
Loading…
Reference in New Issue