No clue what is going on in the collection protocol for Linked List extension page 61

12%20AM

Can anyone explain what each line does? I’ve understood everything in this chapter so far except for this part. I’m genuinely lost.

IMO, the implementation of “func ==” is not necessarily complicated and as confused.

My scheme:
static public func == (lhs: Index, rhs: Index) → Bool {
return lhs.node === rhs.node
}

The implementation of “func <” is correct and “<” means Index lhs is on the left of Index rhs, in other words, the value pointed by lhs is before the value pointed by the rhs in the linkedlist.

demo script for clarity:

var list = LinkedList()
for i in 1…3 {
list.append(i)
}
print(list, “\n”)

let nodes = sequence(first: list.startIndex.node) { $0?.next }
for node in nodes {
print(node)
}
print()

let indexOfNumberTwo = list.index(after: list.startIndex)
print(nodes.contains { $0 === indexOfNumberTwo.node })

The output:
1 → 2 → 3

Optional(1 → 2 → 3 )
Optional(2 → 3 )
Optional(3)
nil

true

I believe you can understand the script if you are capable to complete the whole chapter.

As I understand it, the code overloads the == and < operators to ensure Index’ compliance to the Comparable protocol. This is quite well explained in chapter 16 of “Swift Apprentice”, if you happen to own the book.

The == function determines in what case the two values that are being compared should be equal (I imagine lhs meaning lefthandside and rhs righthandside respectively). The “areequal”-case is represented by a “true” value being returned by this function. So two Indices are equal if their associated nodes (lhs.node and rhs.node) are equal, that means if both reference the exact same instance (first switch case) or if both are nil (second switch case).

The < function first checks if the Indices (lhs and rhs) are equal and returns false right away if that is the case. False means that the left Index (lhs) is defined as NOT being smaller than the right Index (rhs). If they are not equal the next line uses the sequence(first:next:) method to generate a sequence of nodes starting with the node of the left Index. The .contains method then checks this sequence if it contains the node of the right Index (rhs.node). If it does, then the node (or Index respectively) must come AFTER the left Index (or its node) and is thus “bigger” in value than the left one. In this case the function returns true (which means that the lhs Index is smaller or “<” than the rhs Index)

These two functions let the compiler figure out how to compare two “Index” instances. After all they are custom-made and not a standard type like Int or Double (which, of course, also adopt the Comparable protocol behind the scenes), so the compiler wouldn’t know what the heck to do if you wrote “index1 == index2”.

Strictly speaking, you would also need to overload the “>”, “<=” and “>=” operators, but those are implemented by the standard library by means of inferring from your declaration of the “==” and “<” operators.

I hope that helped a little.

1 Like

Why in the == function the comparison is left.next === right.next instead of left === right?