#Flat list to hierarchy

6 messages · Page 1 of 1 (latest)

native oxide
#

Hello, I'm stuck at converting a flat list to a hierarchical structure.

#[derive(Debug, Clone)]
struct Node {
    level: u8,
    children: Vec<Node>
  }
  

fn node_list_to_hierarrchy(nodes: Vec<Node>) -> Option<Node>{
    // check if we even have nodes
    if nodes.len() == 0{
      return None;
    }
    // the first node is always the lone root node
    let mut root_node = nodes[0].clone();
    // init vars
    let mut parent: &mut Node = &mut root_node;
    let mut prev: &mut Node = parent;
    let mut parent_stack: Vec<&mut Node> = Vec::new();
    parent_stack.push(parent);
    // start converting the list to a hierachy
    for node in nodes.iter().skip(1){
        // if the node is a child of the previous node
        if node.level > prev.level{
            // add the previous node to the parent stack
            parent_stack.push(prev);
            // set the previous node as the parent
            parent = prev;
        }
        // if the node is of the same or lower level than the parent node
        else if node.level <= parent.level{
            // remove nodes from the parent stack until we find the parent of the node
            while node.level <= parent.level{
                parent_stack.pop();
                parent = *parent_stack.last().unwrap();
            }
        }
        // add the node to the parent
        parent.children.push(node.clone());
        // set the previous node
        prev = parent.children.last_mut().unwrap();
    }
    Some(root_node)
}
#
fn main() {
    let mut nodes: Vec<Node> = Vec::new();
    nodes.push(Node{level: 0, children: Vec::new()});
    nodes.push(Node{level: 1, children: Vec::new()});
    nodes.push(Node{level: 2, children: Vec::new()});
    nodes.push(Node{level: 3, children: Vec::new()});
    nodes.push(Node{level: 2, children: Vec::new()});
    nodes.push(Node{level: 3, children: Vec::new()});
    nodes.push(Node{level: 1, children: Vec::new()});

    let root_node = node_list_to_hierarrchy(nodes);
}
#

I can't seem to figure out how to do this within Rust due to the borrowship rules.

native oxide
#

Following is the closest I got to work

#
fn add_children(parent: &mut Node, nodes: &[Node], offset: usize) {
    for i in offset + 1..nodes.len() {
        let mut node = nodes[i].clone();
        if node.level == parent.level + 1 {
            add_children(&mut node, nodes, i);
            parent.children.push(node.clone());
        } else if node.level <= parent.level {
            break;
        }
    }
}

fn convert_to_hierarchy(nodes: &[Node]) -> Option<Node> {
    if nodes.is_empty() {
        return None;
    }

    let mut root = nodes[0].clone();
    add_children(&mut root, nodes, 0);
    Some(root)
}```
#

but it uses recursion, and only works if the level difference is 1