-
-
Save VNGXR/0362888b286edf244839557b6cd2918a to your computer and use it in GitHub Desktop.
This file contains hidden or 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
| import Foundation | |
| public struct OrderedSet<Element: Hashable>: Collection, ExpressibleByArrayLiteral { | |
| public typealias Index = Int | |
| private var set: Set<Element> = [] | |
| private var storage: [Element] = [] | |
| public init(arrayLiteral elements: Element...) { | |
| self.init(elements) | |
| } | |
| public init<T: Sequence>(_ sequence: T) where T.Element == Element { | |
| set = Set(sequence) | |
| storage = Array(set) | |
| } | |
| public var startIndex: Int { storage.startIndex } | |
| public var endIndex: Int { storage.endIndex } | |
| public func index(after i: Index) -> Index { storage.index(after: i) } | |
| public func index(before i: Index) -> Index { storage.index(before: i) } | |
| public subscript(index: Index) -> Element { | |
| get { storage[index] } | |
| set { | |
| guard newValue != storage[safe: index] else { return } | |
| storage[index] = newValue | |
| self = .init(storage) | |
| } | |
| } | |
| public mutating func insert(_ element: Element, at index: Index) { | |
| self = inserting(element, at: index) | |
| } | |
| public mutating func append(_ element: Element) { | |
| self = appending(element) | |
| } | |
| public mutating func remove(at index: Index) { | |
| self = removing(at: index) | |
| } | |
| public mutating func remove(_ element: Element) { | |
| self = removing(element) | |
| } | |
| public func inserting(_ element: Element, at index: Index, forced: Bool = true) -> Self { | |
| guard !(!forced && set.contains(element)) else { return .init(storage) } | |
| let a = dropFirst(index) | |
| let b = [element] | |
| let c = dropLast(count - index) | |
| return .init(a + b + c) | |
| } | |
| public func appending(_ element: Element) -> Self { | |
| .init(storage + [element]) | |
| } | |
| public func removing(at index: Index) -> Self { | |
| guard let element = storage[safe: index] else { return .init(storage) } | |
| return removing(element) | |
| } | |
| public func removing(_ element: Element) -> Self { | |
| return .init(storage.filter { $0 != element }) | |
| } | |
| } | |
| extension Sequence where Iterator.Element: Hashable { | |
| public func unique() -> OrderedSet<Element> { .init(self) } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment