这儿每天共享一个 iOS 的新知识,快来重视我吧

前语

我相信大多数人听过慵懒调集(lazy collections),可是却很少用到。慵懒调集与常规调集功能相似,但它改变了 mapfilterreduce 等高阶函数的处理方式。在某些状况下运用慵懒调集能够提高应用的功能。

今天的文章主要来介绍一下如何运用慵懒调集。

lazy collection

慵懒调集也是调集的一种,只不过它在进行某些核算的时分会推延进行,比如数组的遍历取值时,它往往不会直接遍历一切的元素,而是直到真正用到某个元素的时分才会履行,这在许多不同的状况下都是有益的,而且能够防止很多不用的功能开销。

咱们先来举个比如,有一个数字调集,我需求先把偶数筛选出来,再把筛选出的成果乘以 2,终究得到成果。正常的代码是这样的:

var numbers: [Int] = [1, 2, 3, 4]
let modifiedNumbers = numbers
    .filter { number in
        print("履行了 filter")
        return number % 2 == 0
    }.map { number -> Int in
        print("履行了 map")
        return number * 2
    }
print(modifiedNumbers)
// 打印成果
//履行了 filter
//履行了 filter
//履行了 filter
//履行了 filter
//履行了 map
//履行了 map
//[4, 8]

履行的成果契合咱们的预期,先把 numbers 每个元素走了一遍 filter,过滤出偶数(2 和 4),然后再用 map 函数把过滤出的两个数乘 2,终究成果是 [4, 8]。

接下来咱们用慵懒调集重写这块代码,运用慵懒调集只需求在调集后加上 .lazy 关键字:

let modifiedNumbers = numbers
    .lazy
    .filter { number in
        print("履行了 filter")
        return number % 2 == 0
    }.map { number -> Int in
        print("履行了 map")
        return number * 2
    }
print(modifiedNumbers)
// 打印成果
//LazyMapSequence<LazyFilterSequence<Array<Int>>, Int>(_base: Swift.LazyFilterSequence<Swift.Array<Swift.Int>>(_base: [1, 2, 3, 4], _predicate: (Function)), _transform: (Function))

从成果能够看出,终究打印了一个 LazyMapSequence<LazyFilterSequence<Array<Int>> 目标,而 filtermap 的循环一次都没有走进去。原因正是咱们上边提到的,运用 lazy 之后只要真正用到某个元素的时分才会履行

咱们尝试打印成果中的第一个值:

print(modifiedNumbers.first)
// 打印成果
//履行了 filter
//履行了 filter
//履行了 map
//Optional(4)

从打印成果能够看出,当咱们获取第一个值的时分,先走了两次 filter,找出第一个契合条件的数字 2,然后走了一次 map 把终究成果算出来 4。如果咱们仅仅是想获取成果中的第一个值,那么运用 lazy 的功能要比不运用 lazy 好的多,尤其是数组非常大的时分。

什么时分应该运用慵懒调集

也不是一切状况都合适运用慵懒调集,比如当你的数组中元素不多时,其实用不用慵懒调集功能都不会有差别,理论上来说只要当你调集非常大,而你又只需求运用一小部分数据(不需求每个都核算一遍)的时分运用慵懒调集比较合适

还有一种状况是当核算的下流还有其他函数时,它会把上游每一个核算出的值优先走下流的函数,比如你要过滤出 0 – 100000000 之间一切的偶数,并乘以 2,这是很慢的进程。而 lazy 的行为是每次核算出一个偶数就会履行一下乘以 2 的操作,而不是把一切值核算完成后再乘 2,适用于边核算边出成果的状况。

还有一点需求留意,慵懒调集核算出的成果并不会缓存,就以咱们上边的代码为例,你每次调用 modifiedNumbers.first 都会履行两次 filter 和一次 map。这时分如果你想重复运用核算出的值,就需求你先把成果缓存起来,下次运用直接运用缓存值,防止重新核算一次。

本文同步自微信公众号 “iOS新知”,每天按时共享一个新知识,这儿只是同步,想要及时学到就来重视我吧!