完整参考信息这里。
(如果您正在寻找Swift中的数据结构,它们已被移至这里)
SwiftSequence是一个轻量级的框架,用于扩展SequenceType
。它没有超出Swift标准库的要求。每个函数和方法都有严格和懒加载版本,除非另有说明。
要使紧急序列变得懒惰,可以使用lazy
属性。
[1, 2, 3].lazy.hop(2)
// 1, 3
欢迎贡献!任何与序列相关、适用于Linux以及包含一个或多个测试的内容都受欢迎。
func reduce
(@noescape combine: (accumulator: Generator.Element, element: Generator.Element) throws -> Generator.Element)
rethrows -> Generator.Element?
此函数与标准库中的reduce功能相同,只是它将self的第一个元素作为初始值。它返回一个可选值,如果self为空,则为nil。
[1, 2, 3, 4].reduce(+) == 10
返回一个数组,其中包含对self中连续元素调用combine并累加器结果的中间结果
[1, 2, 3].scan(0, combine: +)
[1, 3, 6]
此数组的最后一个元素将与调用reduce以相同参数时的结果相等。
还有类似于reduce的版本,它将序列的第一个元素作为初始值
。
[1, 2, 3, 4, 5].scan(+)
[3, 6, 10, 15]
如果被调用的序列是懒加载的,则此版本也按需计算。
此函数返回直到一个元素对于predicate
返回false的所有self元素
[1, 2, 3, 4, 5, 2].prefixWhile { $0 < 4 }
[1, 2, 3]
请注意,它与filter不同:如果任何元素在第一个返回false的元素之后返回true,它们仍然不会返回。
与prefixWhile
在行为上相似,此函数会移除self
中返回 谓词为真的前几个元素
lazy([1, 2, 3, 4, 5, 2]).dropWhile { $0 < 4 }
4, 5, 2
返回一个元组,第一个元素是长度为n
的self
的前缀,第二个元素是self
的剩余元素。
[1, 2, 3, 4].breakAt(3) == ([1, 2, 3], [4])
这还有一个版本,它接受一个谓词,返回一个元组,其中的第一个元素是直到true
的第一个元素为止的self
的前缀。
这允许以类似Python切片的方式对多个
进行索引。例如,您可以进行非封闭切片let array = [0, 1, 2, 3, 4, 5, 6]
array[3...] == [3, 4, 5, 6]
array[...4] == [0, 1, 2, 3, 4]
array[..<4] == [0, 1, 2, 3]
您也可以通过切片进行修改
var array = [0, 1, 2, 3, 4, 5, 6]
array[...3] = [10, 11, 12, 13]
array == [10, 11, 12, 13, 4, 5, 6]
或者,您可以在数组中跳过元素
let array = [0, 1, 2, 3, 4, 5, 6]
array[2..., by: 2] // [2, 4, 6]
这些函数允许在序列中以统一间隔懒惰或积极地插入元素。
此函数返回插入了元素之间的self
[1, 2, 3].interpose(10)
[1, 10, 2, 10, 3]
可以指定插入元素的时间间隔
[1, 2, 3, 4, 5].interpose(10, n: 2)
[1, 2, 10, 3, 4, 10, 5]
可以插入多个元素
[1, 2, 3].interpose([10, 20])
[1, 10, 20, 2, 10, 20, 3]
可以指定间隔
[1, 2, 3, 4, 5].interpose([10, 20], n: 2)
[1, 2, 10, 20, 3, 4, 10, 20, 5]
此函数允许您通过交替从每个序列中选择元素来组合两个序列
interdig([1, 2, 3], [10, 20, 30])
[1, 10, 2, 20, 3, 30]
可以指定间齿长度
interdig([1, 2, 3, 4, 5], [10, 20, 30, 40, 50, 60], s0Len: 2, s1Len: 3)
[1, 2, 10, 20, 30, 3, 4, 40, 50, 60, 5]
这些函数返回有或没有重复的组合,懒惰或积极。这些函数的懒惰版本不保留底层序列的懒惰性,但它们按需生成组合,既不存储未来的组合也不存储过去的组合,例如
let lazySequence = [1, 2, 3].lazy
let lazyCombos = lazySequence.lazyCombinations(2)
// Here, lazySequence was evaluated, but no combinations have yet been evaluated.
var g = lazyCombos.generate()
g.next() == [1, 2]
// Here, only one combination has been evaluated, and only that combination is stored in memory
g.next() == [1, 3]
// Here, two combinations have been evaluated, but no extra combinations have been stored in memory.
返回长度为n
的自我不重复组合
组合按照自我顺序的词法顺序返回
[1, 2, 3].combinations(2)
[1, 2], [1, 3], [2, 3]
要使组合懒惰生成并按需生成,请使用lazyCombinations()
。
示例配方
extension CollectionType {
func powerSet() -> FlatMapSeq<LazyForwardCollection<Self>, ComboSeq<[Self.Generator.Element]>> {
var i = 0
return lazy(self).flatMap { _ in self.lazyCombinations(++i) }
}
}
[1, 2, 3] // [1], [2], [3], [1, 2], [1, 3], [2, 3], [1, 2, 3]
.powerSet()
返回自我重复长度为n
的组合。
组合按照自我顺序的词法顺序返回
[1, 2, 3].combinationsWithRep(2)
[1, 1], [1, 2], [1, 3], [2, 2], [2, 3], [3, 3]
要生成组合并进行按需生成,请使用lazyCombinationsWithRep()
。
这些函数按字典顺序返回排列的self
,如果self
不是字典序中的第一个排列,则不会返回所有排列。(要返回所有排列,可以使用sort()
)。此函数可以作用于 元素集合,或者如果提供了关闭 ,则可以作用于任何集合。从懒惰的角度来看,它与组合函数的行为相同:强制评估底层集合,但可以懒惰地生成每个新的排列。要访问懒惰版本,请使用带有 前缀的这些函数版本。(例如,lexPermutations()
变为lazyLexPermutations()
)
[1, 2, 3].lexPermutations()
[[1, 2, 3], [1, 3, 2], [2, 1, 3], [2, 3, 1], [3, 1, 2], [3, 2, 1]]
[3, 2, 1].lexPermutations()
[[3, 2, 1]]
[1, 2, 3].lexPermutations(<)
[[1, 2, 3], [1, 3, 2], [2, 1, 3], [2, 3, 1], [3, 1, 2], [3, 2, 1]]
[1, 2, 3].lexPermutations(>)
[[1, 2, 3]]
这些函数使用了与字典序排列相同的算法,但会对自身索引进行排列。(不返回索引,只是用于排列)
[1, 2, 3].permutations()
[[1, 2, 3], [1, 3, 2], [2, 1, 3], [2, 3, 1], [3, 1, 2], [3, 2, 1]]
lazy([3, 2, 1]).lazyPermutations()
[3, 2, 1], [3, 1, 2], [2, 3, 1], [2, 1, 3], [1, 3, 2], [1, 2, 3]
这些函数返回一个自身周期。如果未指定周期数,则无限循环自身。
在LazySequenceType
对象上调用时,返回的序列是惰性的,否则是急切的。(然而,无限周期总是惰性的)
[1, 2, 3].cycle(2)
[1, 2, 3, 1, 2, 3]
[1, 2, 3].cycle()
1, 2, 3, 1, 2, 3, 1...
这些函数可用于根据某些条件对序列的元素进行分组。
func categorise<U : Hashable>(keyFunc: Generator.Element -> U) -> [U:[Generator.Element]]
此函数将自身所有元素分类到字典中,该字典的键由keyFunc
指定。
[1, 2, 3, 4, 5, 6].categorise { $0 % 2 }
[
0: [2, 4, 6],
1: [1, 3, 5]
]
(此函数没有惰性版本)
此函数返回一个字典,其中键是自身中的元素,值是它们各自的比例。
[1, 1, 1, 2, 2, 3].freqs()
[
1: 3,
2: 2,
3: 1
]
(此函数没有惰性版本)
返回没有重复的self
。
[1, 2, 3, 2, 2, 4, 1, 2, 5, 6].uniques()
[1, 2, 3, 4, 5, 6]
由于categorise()
和freqs()
不能有惰性版本,因此这些分组函数提供了类似的行为。它们不是基于整个序列进行分类,而是基于相邻值进行分类。
这会对相邻的相同值进行分组。
lazy([1, 2, 2, 3, 1, 1, 3, 4, 2]).group()
[1], [2, 2], [3], [1, 1], [3], [4], [2]
这根据闭包对相邻的相同值进行分组。
lazy([1, 3, 5, 20, 22, 18, 6, 7]).group { abs($0 - $1) < 5 }
[1, 3, 5], [20, 22, 18], [6, 7]
这将对返回keyFunc
相同结果的相邻值进行分组。
lazy([1, 3, 5, 2, 4, 6, 6, 7, 1, 1]).groupBy { $0 % 2 }
[1, 3, 5], [2, 4, 6, 6], [7, 1, 1]
这些函数将序列分割开。
此函数返回self
,分割成长度为n
的不重叠数组。
[1, 2, 3, 4, 5].chunk(2)
[[1, 2], [3, 4], [5]]
此函数返回self
,分割成长度为n
的重叠数组。
[1, 2, 3, 4, 5].window(3)
[[1, 2, 3], [2, 3, 4], [3, 4, 5]]
这只是添加了一个名为specEnumerate()
的函数,它与标准库中的enumerate()
相同,只不过它返回的索引是特定于基本类型,而不是仅仅是Int
。例如,这个:
"hello".characters.specEnumerate()
将返回一个包含(String.Index, Character)
的序列(而不是标准库中的enumerate()
返回的(Int, Character)
,即Int和Character元组的组合)。此函数没有急切版本(正如急切版枚举函数)。
这里的方法旨在替换类似于这样的模式
[1, 2, 3, 4, 5, 6].filter { n in n > 4 }.first
[1, 2, 3, 4, 5, 6].filter { n in n % 2 == 0 }.count
在这里,filter与CollectionType
属性(如first
或count
)链接使用。
这些链完全无效率:它们不需要地分配和填充数组。即使使用lazy
属性,实际操作也是出乎意料的。例如,下面的代码:
var i = 0
[1, 2, 3, 4, 5, 6]
.lazy
.filter { n in
print(++i)
return n > 4
}.first
将打印从一到十。
提供了first
、last
和count
方法,它们都接受谓词,以及indicesOf
和lastIndexOf
。
还提供了一个partition
方法,该方法将self
分割为满足和不满足predicate
的数组元组。
允许惰性转置和急切转置。在惰性转置时,每行都会急切地计算,但只计算该行
let transposed = lazy([
[1, 2, 3],
[1, 2, 3],
[1, 2, 3]
]).transpose()
var g = transposed.generate()
g.next() == [1, 1, 1]
// Each row is an eager array, but only that row is evaluated.
g.next() == [2, 2, 2]
// It's safe to use with single-pass sequences, also, as each sequence is only evaluated once.
支持惰性和急切的笛卡尔积。
product([1, 2], [3, 4])
[[1, 3], [1, 4], [2, 3], [2, 4]]
lazyProduct([1, 2], [3, 4])
[1, 3], [1, 4], [2, 3], [2, 4]
这些函数允许您将两个不同长度的序列连结起来,并指定较短的序列的填充值。如果未指定,则填充值为nil
。此函数没有急切版本(没有急切的库版本)
zipWithPadding([1, 2, 3], [1, 2], pad0: 100, pad1: 900)
(1, 1), (2, 2), (3, 900)
zipWithPadding([1, 2, 3], [1, 2])
(1?, 1?), (2?, 2?), (3?, nil)