3

Swift 的标准库是否包含a或类似内容的列表变形Sequence

列表或序列上的 Anamorphism 与reduce函数相反。因此,它不会将序列折叠为单个值,而是构建一个序列。

reduce接受一个初始值,以及一个用于将序列元素与 this 组合的函数,并返回一个最终值。它的签名看起来像这样(为可读性添加了换行符):

public func reduce<Result>(
  _ initialResult: Result, 
  _ nextPartialResult: (Result, Self.Element) throws -> Result) rethrows
  -> Result

序列的变形可能是这样的:

func inflate<State, Element>(
  _ initialState: State, 
  _ generator: @escaping (State) -> (State, Element)?)
  -> AnamorphismSequence<State, Element>

通过给它一些初始状态,并告诉它如何把它变成一个元素和下一个状态,它可以为你建立一个序列。所以,我可以得到一个像这样的数组Array(1..<10)

Array(inflate(1) { s in s < 10 ? (s+1, s) : nil })
4

1 回答 1

3

Swift 有两种变体。两种类型都有私有初始化器,但它们可以使用各自的全局函数生成。

  1. UnfoldSequence<Element, State>, 由sequence(state:next:)

  2. UnfoldFirstSequence<Element>这是由sequence(first:next:)

后者不做前者做不到的事情。它只是一个简化版本,当您不需要单独的状态时使用它,而不仅仅是知道前一个元素是什么。

以下是1..<10使用这两种方法实现示例的方法:

Array(sequence(first: 1) { i in (i < 9) ? (i + 1) : nil })

Array(sequence(state: 1) { state -> Int? in 
    defer { state += 1 }
    return state < 10 ? state : nil
})

您的示例更适合更简单的sequence(first:next:). 后者对于产生完美正方形的序列更有用:*您保持的状态将是完美正方形的平方(每次展开时增加 1)*您的序列通过将该状态乘以自身来产生它的元素(平方它)

从技术上讲,您可以使用捕获的局部变量来模拟 的状态UnfoldSequence,但这有点混乱,而且几乎可以肯定更慢。

于 2019-07-30T21:17:17.247 回答