Last active
May 19, 2020 22:46
-
-
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)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// 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