Reputation: 11
What follows is a simple snippet of code defining a Node class for representing linked lists and a method for adding a node to the end of a list. In the code, there are two vars. How can I write this code without any vars?
case class Node[A](data: A, var next: Option[Node[A]])
def addNodeToEnd[A](node: Node[A], nodeToAdd: Node[A]): Node[A] = {
if (node.next == None) {
node.next = Some(nodeToAdd)
} else {
var current = node
while ( current.next != None) {
current = current.next.getOrElse(current)
}
current.next = Some(nodeToAdd)
}
node
}
//Test
val node = Node(1, Some(Node(2, Some(Node(3, None)))))
val nodeToAdd = Node(88, None)
println(addNodeToEnd(node, nodeToAdd))
Upvotes: 1
Views: 123
Reputation: 51271
Here's one approach. No var
s. No mutation.
case class Node[A](data: A, next: Option[Node[A]])
def addToEnd[A](node: Node[A], toAdd: A): Node[A] =
node.next.fold(node.copy(next = Some(Node(toAdd,None))))(
n => node.copy(next = Some(addToEnd(n,toAdd))))
//Test
val list = Node(1, Some(Node(2, Some(Node(3, None)))))
addToEnd(list, 88)
//res0: Node[Int] = Node(1,Some(Node(2,Some(Node(3,Some(Node(88,None)))))))
Or, if you prefer...
def nodeAppend[A](ns: Node[A], toAppnd: Node[A]): Node[A] =
ns.next.fold(ns.copy(next = Some(toAppnd)))(
nxt => ns.copy(next = Some(nodeAppend(nxt, toAppnd))))
//Test
val list = Node(1, Some(Node(2, None)))
val listToAdd = Node(88, Some(Node(99,None)))
nodeAppend(list, listToAdd)
//res0: Node[Int] = Node(1,Some(Node(2,Some(Node(88,Some(Node(99,None)))))))
Upvotes: 1