我有很多对象,我需要将它们分成两个组成一组,以供UI助手使用。
例:
[0, 1, 2, 3, 4, 5, 6]
通过这四个数组成为一个数组
[[0, 1], [2, 3], [4, 5], [6]]
有很多分割数组的方法。但是,如果阵列很大,什么是最有效的(成本最低)。
如果您正在寻找效率,则可以使用一种方法来懒散地生成每个包含2个元素的数组,因此您一次只能在内存中存储2个元素:
public struct ChunkGen<G : GeneratorType> : 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<S : SequenceType> : SequenceType { private let seq: S private let n: Int public func generate() -> ChunkGen<S.Generator> { return ChunkGen(g: seq.generate(), n: n) } } public extension SequenceType { func chunk(n: Int) -> ChunkSeq<Self> { 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
此方法适用于任何SequenceTypeArray,而不仅限于Arrays。
SequenceType
对于Swift 1,没有协议扩展,您将拥有:
public struct ChunkGen<T> : GeneratorType { private var (st, en): (Int, Int) private let n: Int private let c: [T] public mutating func next() -> ArraySlice<T>? { (st, en) = (en, en + n) return st < c.endIndex ? c[st..<min(en, c.endIndex)] : nil } private init(c: [T], n: Int) { self.c = c self.n = n self.st = 0 - n self.en = 0 } } public struct ChunkSeq<T> : SequenceType { private let c: [T] private let n: Int public func generate() -> ChunkGen<T> { return ChunkGen(c: c, n: n) } } func chunk<T>(ar: [T], #n: Int) -> ChunkSeq<T> { return ChunkSeq(c: ar, n: n) }
对于Swift 3:
public struct ChunkIterator<I: IteratorProtocol> : 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..<n) { guard let x = i.next() else { break } build.append(x) } return build } } public struct ChunkSeq<S: Sequence> : Sequence { fileprivate let seq: S fileprivate let n: Int public func makeIterator() -> ChunkIterator<S.Iterator> { return ChunkIterator(i: seq.makeIterator(), n: n) } } public extension Sequence { func chunk(_ n: Int) -> ChunkSeq<Self> { 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