Skip to content

Instantly share code, notes, and snippets.

@djk12587
Last active May 19, 2020 22:46
Show Gist options
  • Save djk12587/ea6d8dea837f8274b911deb0c819f74f to your computer and use it in GitHub Desktop.
Save djk12587/ea6d8dea837f8274b911deb0c819f74f to your computer and use it in GitHub Desktop.
Swift: Collection with a cap limit (if new items are added at while count == the cap limit, the oldest item will be popped off)
//
// CappedCollection.swift
// UprightWatchApp Extension
//
// Created by Dan_Koza on 11/29/18.
// Copyright © 2018 DanielKoza. All rights reserved.
//
import Foundation
struct CappedCollection<T> {
private var elements: [T]
var maxCount: Int
init(elements: [T], maxCount: Int) {
self.elements = elements
self.maxCount = maxCount
}
}
extension CappedCollection: Collection, ExpressibleByArrayLiteral {
typealias Index = Int
typealias Element = T
init(arrayLiteral elements: Element...) {
self.elements = elements
maxCount = elements.count
}
var startIndex: Index { return elements.startIndex }
var endIndex: Index { return elements.endIndex }
subscript(index: Index) -> Iterator.Element {
get { return elements[index] }
}
func index(after i: Index) -> Index {
return elements.index(after: i)
}
@discardableResult
mutating func append(_ newElement: Element) -> Element? {
elements.append(newElement)
return removeExtraElements().first
}
@discardableResult
mutating func append<C>(contentsOf newElements: C) -> [Element] where C : Collection, CappedCollection.Element == C.Element {
elements.append(contentsOf: newElements)
return removeExtraElements()
}
@discardableResult
mutating func insert(_ newElement: Element, at i: Int) -> Element? {
elements.insert(newElement, at: i)
return removeExtraElements().first
}
@discardableResult
mutating func insert<C>(contentsOf newElements: C, at i: Int) -> [Element] where C : Collection, CappedCollection.Element == C.Element {
elements.insert(contentsOf: newElements, at: i)
return removeExtraElements()
}
private mutating func removeExtraElements() -> [Element] {
guard elements.count > maxCount else { return [] }
var poppedElements: [Element] = []
poppedElements.append(contentsOf: elements[maxCount..<elements.count])
elements.removeLast(elements.count - maxCount)
return poppedElements
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment