Split large Array in Array of two elements

前端 未结 7 1960
借酒劲吻你
借酒劲吻你 2020-12-20 17:53

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

7条回答
  •  有刺的猬
    2020-12-20 18:17

    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
    

提交回复
热议问题