0

The desired behavior of the following code is that when you call findLinkToRemove() on a Node it will recursively find the last node in the chain and remove it. The actual behavior is that nothing happens because node = nothing is an assignment not a mutation. Is there a way to make it change the field of the parent node to be nothing instead of just assigning the pointer to nothing [without passing the parent as a parameter which I really really don't want to do]?

mutable struct Node
    next::Union{Nothing, Node}
end

function findLinkToRemove(node::Node)
    if node.next === nothing
        node = nothing
    else
        findLinkToRemove(node.next)
    end
end
Isaac
  • 21
  • 4

1 Answers1

2

You need to look one level deeper:

function findLinkToRemove(node::Node)
    if !(node.next === nothing) && node.next.next === nothing
        node.next = nothing
    else
        findLinkToRemove(node.next)
    end
end

Full code with example (note that your struct needs to be mutable):

mutable struct Node
    descr::Symbol
    next::Union{Nothing, Node}
end
n0 = Node(:n0,nothing)
n1 = Node(:n1, n0)
n2 = Node(:n2, n1)

Testing:

julia> dump(n2)
Node
  descr: Symbol n2
  next: Node
    descr: Symbol n1
    next: Node
      descr: Symbol n0
      next: Nothing nothing

julia> findLinkToRemove(n2)

julia> dump(n2)
Node
  descr: Symbol n2
  next: Node
    descr: Symbol n1
    next: Nothing nothing
Przemyslaw Szufel
  • 40,002
  • 3
  • 32
  • 62
  • `Node` then needs to be defined as `mutable struct Node`, of course. – mbauman Jul 01 '20 at 19:57
  • In my actual application I don't necessarily have access to the parent. So it is possible, for example, that the node passed to the initial function call is the one that I want deleted. So I was hoping for a solution involving updating what is stored at the location of the pointer to 'nothing' instead of reworking the code to make the parent available. – Isaac Jul 01 '20 at 20:06
  • 1
    When you want to mutate an object you need to have a reference to that object. Your function `findLinkToRemove` did not change anything in the tree. Julia uses pass-by-sharing, your `next` field would have to be e.g. one element Array to make it possible to pass it for mutation. – Przemyslaw Szufel Jul 01 '20 at 20:22
  • Ah that is an interesting solution, I don't suppose there is a way to pass a reference for mutation without wrapping it in an array? I think that I am just going to make it like a linked list and add a pointer to the parent node in the app, but I am still interested in the answer just for the sake of my education. – Isaac Jul 01 '20 at 20:31
  • 1
    @Isaac this is a good reading for you: https://stackoverflow.com/questions/58150295/how-to-pass-an-object-by-reference-and-value-in-julia – Przemyslaw Szufel Jul 01 '20 at 22:56