快速浏览链表

This article is about an implementation of Linked Lists in Swift, where you can iterate through the list. The theory of Linked Lists is covered in my own article, as are Linked Lists in Swift. This article is about doing better.

本文是关于在Swift中实现链表的,您可以在其中遍历列表。 我自己的文章中介绍了链表的理论以及Swift中的链表 。 本文是关于做得更好

Difficulty: Beginner | Easy | Normal | Challenging

难度:初学者| 简单 | 普通 | 具有挑战性的

先决条件: (Prerequisites:)

  • Coding in Swift Playgrounds (guide HERE)

    Swift操场上的编码(指南HERE )

This article uses Linked Lists as motivation for implementing the IteratorProtocol. It does help to have some understanding of Linked Lists, but this is not completely necessary.

本文使用链接列表作为实现IteratorProtocol的动机。 了解链接列表确实有帮助,但这不是完全必要的。

My implementation makes use of the defer keyword in Swift.

我的实现在Swift中使用了defer关键字

术语 (Terminology)

快捷术语 (Swift terminology)

Class: An object that defines properties and methods in common

类:共同定义属性和方法的对象

Iterator: In Swift, a protocol that allows you to loop through a sequence. That is, the protocol supplies values one at a time

迭代器:在Swift中,该协议可让您遍历序列。 也就是说,协议一次提供一个值

IteratorProtocol: A protocol that provides the values of a sequence one at a time

IteratorProtocol:一种协议,一次提供一个序列的值

Protocol: A blueprint on methods, properties and requirements to suit a piece of functionality

协议:适合某项功能的方法,属性和要求的蓝图

Sequence: A Protocol that provides sequenced, iterative access to elements of the sequence

序列:一种协议,提供对序列元素的有序,迭代访问

链表术语 (Linked List Terminology)

Data structure: A way of formatting data

数据结构:一种格式化数据的方式

Head: The first (or parent, or root) node

头:第一个(或父或根)节点

Linked List: A linear collection of data elements, made up of a head node with zero or more connected nodes. The order of this list is given by pointers from each node to the next

链表:数据元素的线性集合,由具有零个或多个连接节点的头节点组成。 该列表的顺序由从每个节点到下一个节点的指针给出

Node: The basic unit of a data structure

节点:数据结构的基本单位

Null Pointer: A pointer that does not point to anywhere

空指针:不指向任何地方的指针

Pointer: An object that stores a memory address

指针:存储内存地址的对象

Tail: The linked list, after the head

尾巴:链表,头后

动机 (The Motivation)

Reading out from a Linked List is always quite tricky, and requires some skill, perhaps implementing CustomStringConvertible.

从“链表”中读取数据总是很棘手,并且需要一些技巧,也许是实现CustomStringConvertible

As ever, there is a better way. Step in Sequence.

与以往一样,有更好的方法。 按Sequence

A sequence can be iterated over, and provides great functions like contains(_ :) that users of an API expect.

sequence可以被迭代,并提供API用户期望的出色功能,例如contains(_ :)

迭代器 (An Iterator)

Any Loop in Swift can be iterated (often using for…in).

Swift中的任何Loop都可以迭代(通常使用for…in )。

A simple example

一个简单的例子

let numbers: [Int] = [1,2,3]
for num in numbers {
print (num)
}

This is known as the iterator design pattern (or at least this is implemented in the background for you).

这称为迭代器设计模式(或者至少在后台为您实现)。

A custom type can conform to Sequence by implementing makeIterator() (a factory method that returns the specific iterator for the type) into the type. Trust me, although a sequence is simply a list of elements it enables you to perform useful operations that you will want to use…trust me!

通过将makeIterator() (一种返回该类型特定迭代器的工厂方法makeIterator()实现为类型,自定义类型可以符合Sequence 。 相信我,尽管序列只是元素列表,它使您能够执行想要使用的有用操作……相信我!

链接列表示例 (The Linked List Example)

为什么是链表? (Why a Linked List?)

Since Array conforms to the Collection protocol so already implemenents iterators.

由于Array符合Collection协议,因此已经实现了迭代器。

This means minimal examples making arrays conform to sequence and their elements to IteratorProtocol are rather superfluous.

这意味着使数组符合序列的示例最少,而IteratorProtocol的元素则是多余的。

Instead, let us use a Linked List as our example.

相反,让我们以链接列表为例。

基本链表 (The Basic Linked List)

我的基本实施 (My Basic Implementation)

I’ve implemented a Linked List many times, but seldom with the LinkedList class expressed below that holds the head of the Linked List.

我已经实现了链接列表很多次,但是很少使用下面表示的LinkedList类来容纳Linked List的头部。

遍历节点 (Iterating Through Nodes)

The problem that I wish to solve is to iterate over the nodes.

我要解决的问题是遍历节点

for element in list {
print(element.item)
}

The Swift compiler helps out, by telling us that we’re missing something. In this case, we are missing out conformance to the Sequence protocol.

Swift编译器通过告诉我们我们缺少了一些东西来提供帮助。 在这种情况下,我们会丢失与Sequence协议的一致性。

Image for post

So we are going to…

所以我们要...

符合序列协议 (Conform to the Sequence Protocol)

The LinkedList class will conform to the Sequence protocol.

LinkedList类将符合Sequence协议。

To do so, we need to implement a makeIterator() method that returns an iterator.

为此,我们需要实现一个返回迭代器的makeIterator()方法。

Now the AnyIterator struct is the item we are looking for, and because we are returning a Node there is no particular problem in Swift.

现在, AnyIterator结构是我们要查找的项目,并且由于我们要返回Node,因此Swift中没有任何特殊问题。

So the makeIterator() method is hit just once, returning our AnyIterator which will return the next() element.

因此, makeIterator()方法仅被命中一次,返回了我们的AnyIterator ,它将返回next()元素。

Let us look at the makeIterator() in detail:

让我们详细看一下makeIterator()

which can be called through the following:

可以通过以下方式调用:

So we ask the Linked List to create an iterator, and it provides us with next() each time, until there is no extra element in the Linked List.

因此,我们要求链表创建一个迭代器,并每次为我们提供next() ,直到链表中没有多余的元素。

Instead of the while loop we can just use a for…in loop

代替while循环,我们可以使用for…in循环

This particular implementation bears repeatability, that is we can iterate over the elements of LinkedList twice and the elements are read out of the LinkedList twice!

这种特定的实现承担重复性,这是我们可以遍历链表的元素两次,元素LinkedList的读出一倍!

符合序列协议和IteratorProtocol (Conform to the Sequence Protocol AND IteratorProtocol)

We can, instead, take another approach. We can make our LinkedList class conform to both Sequence and IteratorProtocol, which is perhaps easier to understand since we just implement the next() function.

相反,我们可以采取另一种方法。 我们可以使LinkedList类同时符合SequenceIteratorProtocol ,这也许更容易理解,因为我们只是实现了next()函数。

The code? Pretty easy since we return our head node, and then once the closure is out of scope move onto the next node in the list.

代码? 因为我们返回了头节点,所以非常容易,一旦关闭超出范围,就移至列表中的下一个节点。

This is all fine, and works as before in that we can print out the elements in the list. But what if we filter(_:) after?

一切都很好,并且像以前一样工作,因为我们可以打印出列表中的元素。 但是如果我们在之后filter(_:)怎么办?

But…but there is an element with 1 in our Linked list.

但是...但是在链接列表中有一个元素为1的元素。

Yes: but

对,但是

Conforming to the sequence protocol does not guarantee that iterating over the elements is non-destructive

遵守序列协议不能保证对元素的迭代是非破坏性的

We aren’t guarenteed repeated access when iterating over our elements.

遍历元素时,我们不保证重复访问。

This bears repeating, in it’s own heading

在标题上需要重复

序列协议:重复访问 (The Sequence Protocol: Repeated Access)

Conforming to the sequence protocol does not guarantee that iterating over the elements is non-destructive.

遵守序列协议不能保证对元素的迭代是非破坏性的。

In order to guarentee this we should conform to the collection protocol.

为了确保这一点,我们应该遵守收集协议。

结论: (Conclusion:)

Iteration over a sequence can be finite or infinite (imagine a circular queue). In any case, conforming to sequence seems like a pretty good deal, you get the for…in pattern as well as lots of fun functions like contains and filter.

序列上的迭代可以是有限的或无限的(想象一个循环队列)。 无论如何,遵循顺序似乎是一件很不错的事情,您可以使用for…in模式以及许多有趣的功能,例如containsfilter

However, we need to be mindful if our iteration is destructive or not. We don’t get any guarantees from Swift so need to make sure that we understand the code that we are writing and understand the benefits of the different approaches using Sequence and IteratorProtocol

但是,我们需要注意迭代是否具有破坏性。 我们没有从Swift获得任何保证,因此需要确保我们了解我们正在编写的代码,并了解使用Sequence和IteratorProtocol的不同方法的好处

进一步研究: (Further study:)

Apple have documentation on Sequence. I would recommend this article about Linked Lists in Swift (Ok, I wrote it — but still…).

苹果有有关Sequence的文档 。 我会推荐这篇有关Swift中的链表的文章 (好吧,我写了,但是仍然……)。

Twitter联系人: (The Twitter contact:)

Any questions? You can get in touch with me HERE

任何问题? 您可以在这里与我联系

翻译自: https://medium.com/@stevenpcurtis.sc/iterate-through-a-linked-list-in-swift-c1bc7ef14e07

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值