Skip to content

Instantly share code, notes, and snippets.

@VNGXR
Forked from maximkrouk/OrderedSet.swift
Created March 18, 2020 12:40
Show Gist options
  • Select an option

  • Save VNGXR/0362888b286edf244839557b6cd2918a to your computer and use it in GitHub Desktop.

Select an option

Save VNGXR/0362888b286edf244839557b6cd2918a to your computer and use it in GitHub Desktop.
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