I have large list of objects and I need to split them in a group of two elements for UI propouse.
Example:
[0, 1, 2, 3, 4, 5, 6]
Becomes
If you're looking for efficiency, you could have a method that would generate each array of 2 elements lazily, so you'd only store 2 elements at a time in memory:
public struct ChunkGen : GeneratorType {
private var g: G
private let n: Int
private var c: [G.Element]
public mutating func next() -> [G.Element]? {
var i = n
return g.next().map {
c = [$0]
while --i > 0, let next = g.next() { c.append(next) }
return c
}
}
private init(g: G, n: Int) {
self.g = g
self.n = n
self.c = []
self.c.reserveCapacity(n)
}
}
public struct ChunkSeq : SequenceType {
private let seq: S
private let n: Int
public func generate() -> ChunkGen {
return ChunkGen(g: seq.generate(), n: n)
}
}
public extension SequenceType {
func chunk(n: Int) -> ChunkSeq {
return ChunkSeq(seq: self, n: n)
}
}
var g = [1, 2, 3, 4, 5].chunk(2).generate()
g.next() // [1, 2]
g.next() // [3, 4]
g.next() // [5]
g.next() // nil
This method works on any SequenceType
, not just Arrays.
For Swift 1, without the protocol extension, you've got:
public struct ChunkGen : GeneratorType {
private var (st, en): (Int, Int)
private let n: Int
private let c: [T]
public mutating func next() -> ArraySlice? {
(st, en) = (en, en + n)
return st < c.endIndex ? c[st.. : SequenceType {
private let c: [T]
private let n: Int
public func generate() -> ChunkGen {
return ChunkGen(c: c, n: n)
}
}
func chunk(ar: [T], #n: Int) -> ChunkSeq {
return ChunkSeq(c: ar, n: n)
}
For Swift 3:
public struct ChunkIterator : IteratorProtocol {
fileprivate var i: I
fileprivate let n: Int
public mutating func next() -> [I.Element]? {
guard let head = i.next() else { return nil }
var build = [head]
build.reserveCapacity(n)
for _ in (1.. : Sequence {
fileprivate let seq: S
fileprivate let n: Int
public func makeIterator() -> ChunkIterator {
return ChunkIterator(i: seq.makeIterator(), n: n)
}
}
public extension Sequence {
func chunk(_ n: Int) -> ChunkSeq {
return ChunkSeq(seq: self, n: n)
}
}
var g = [1, 2, 3, 4, 5].chunk(2).makeIterator()
g.next() // [1, 2]
g.next() // [3, 4]
g.next() // [5]
g.next() // nil