Sina
Sina

Reputation: 168

create ListNode from Vec with ref to first Node

#[derive(PartialEq, Eq, Clone, Debug)]
pub struct ListNode {
    pub val: i32,
    pub next: Option<Box<ListNode>>,
}

impl ListNode {
    #[inline]
    fn new(val: i32) -> Self {
        ListNode { next: None, val }
    }
}


fn create_list(list : Vec<i32>) -> Option<Box<ListNode>> {
    // the code should be written this place
}


i have ListNode struct like this and dont't want to edit this struct and impl. i get a list of i32 number as Vec and i want to create ListNode that each item in list point next item and at the end return first number

for example get vector like this [1,2,3] and at the end return object like this (i want to create programmatically and this is hand made)

ListNode { 
   val : 1,
   ListNode { 
      val : 2,
      next:ListNode { 
          next: None,
          val : 3
      }
   }
}

i can't hold first ListNode and return that while dealing with rust borrowing and ownership

-- Update --

i am new to rust. so i create an example from the way i want to solve this problem. this example written in typescript

class ListNode {
     val: number
     next: ListNode | null
     constructor(val?: number, next?: ListNode | null) {
         this.val = (val===undefined ? 0 : val)
         this.next = (next===undefined ? null : next)
     }
     toString(): string {
        return `ListNode ${this.val}${this.next===null? "" : '  => '+ this.next.toString()}`
     }
 }


function createList(list : number[]) : ListNode|null {
    const firstItem = new ListNode(0,null);
    let second = firstItem;
    for (let item of list) {
        second.next = new ListNode(item,null)
        second = second.next;
    }
    return firstItem.next;
}

const firstNodePointer = createList([1,2,3,4,5])

console.log(firstNodePointer?.toString())

Upvotes: 0

Views: 229

Answers (2)

杨雪念
杨雪念

Reputation: 31

You can use this macro to create a list of ListNodes

macro_rules! list_node {
    () => {None};
    ($($e:expr), *) => {
        {
            // create a template head
            let mut temp_head = Box::new(ListNode::new(0));
            // use ref_head as a mutable reference to the last node
            let mut ref_head = &mut temp_head;
            $(
                // append a new node to the last node
                ref_head.next = Some(Box::new(ListNode::new($e)));
                ref_head = ref_head.next.as_mut().unwrap();
            )*
            // return the head of the list (skip the template head)
            Some(temp_head.next.unwrap())
        }
    };
}
#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test() {
        let list_nodes = ListNode {
            val: 1,
            next: Some(Box::new(ListNode {
                val: 2,
                next: Some(Box::new(ListNode { val: 3, next: None })),
            })),
        };
        let list_nodes = Some(Box::new(list_nodes));
        assert_eq!(list_nodes, list_node![1, 2, 3]);
    }
}

Upvotes: 0

cafce25
cafce25

Reputation: 27550

This will create the list in one go.

fn create_list(list : Vec<i32>) -> Option<Box<ListNode>> {
    let mut head = None;
    let mut current = &mut head;
    for x in list {
        *current = Some(Box::new(ListNode::new(x)));
        current = &mut current.as_mut().unwrap().next;
    }
    head
}

Upvotes: 3

Related Questions