Skip to content

Instantly share code, notes, and snippets.

@ivanopcode
Created January 23, 2024 18:58
Show Gist options
  • Save ivanopcode/376957326dd9ad87bcb28211d5781c9d to your computer and use it in GitHub Desktop.
Save ivanopcode/376957326dd9ad87bcb28211d5781c9d to your computer and use it in GitHub Desktop.
Swift OrderedStrictidSet data structure draft
// MIT License
//
// Copyright (c) 2024 Ivan Oparin
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
/// An ordered collection of elements with unique identities.
///
/// Use an OrderedStrictidSet when you need to maintain not only the uniqueness
/// of elements based on their explicit identity but also their insertion order.
/// This is ideal in scenarios where the sequence in which elements are added
/// matters, yet each element has a stable, unique identifier that must be
/// preserved. OrderedStrictidSet ensures that, despite any changes in an
/// element's properties, its identity (as defined by its id property) dictates
/// its continued presence and position in the set.
///
/// You can create an OrderedStrictidSet with any element type that conforms to
/// the Identifiable protocol. This makes OrderedStrictidSet suitable for
/// storing complex objects where both identity and order are significant,
/// beyond the object's current state or value.
///
/// ```swift
/// struct Document: Identifiable {
/// let id: Int
/// var title: String
/// }
///
/// var documents: OrderedStrictidSet = [Document(id: 1, title: "Report"),
/// Document(id: 2, title: "Summary")]
/// let updatedDocument = Document(id: 1, title: "Updated Report")
/// documents.update(with: updatedDocument)
///
/// // The 'documents' set maintains the updated Document and its order
/// ```
///
/// Identity-Based Ordered Set Operations
/// ======================================
///
/// OrderedStrictidSet provides operations similar to a standard set, but with
/// the added feature of maintaining the order of elements. These operations
/// are based on the identity of elements rather than their hash values:
///
/// - Use the contains(_:) method to check whether the set contains an
/// element with a specific identifier.
/// - Use the update(with:) method to replace an existing element with a new
/// one, maintaining its original position, as long as they share the same
/// identifier.
/// - Use the remove(_:) method to remove an element based on its identifier
/// without disrupting the order of other elements.
///
/// The operations in OrderedStrictidSet ensure that the order of elements
/// is preserved, aligning with the initial insertion sequence, irrespective
/// of any changes in the properties of the elements.
/// ```swift
/// var projects: OrderedStrictidSet = [Project(id: 1, status: "Starting"),
/// Project(id: 2, status: "In Progress")]
/// let updatedProject = Project(id: 1, status: "Completed")
/// projects.update(with: updatedProject)
/// // The 'projects' set now maintains the updated Project 1 in its original
/// // position and the Project 2
/// ```
/// Preserving Order and Unique Identities
/// ======================================
///
/// OrderedStrictidSet is especially useful in contexts where both the order
/// and the integrity of each element, based on a stable identity, are crucial.
/// This includes applications like task management, playlist curation, or
/// document revision tracking, where the order of elements carries
/// significant meaning.
///
/// ```swift
/// for document in documents {
/// print("Document ID: \(document.id), Title: \(document.title)")
/// }
/// // Prints "Document ID: 1, Title: Updated Report"
/// // Prints "Document ID: 2, Title: Summary"
/// ```
///
/// Unlike standard ordered collections, OrderedStrictidSet does not depend
/// on hash values for order and uniqueness checks, making it an effective
/// choice for scenarios where an object's identity and its sequence in a
/// collection are both of paramount importance.
struct StrictidSet<Element: Identifiable> {
private var _elements: OrderedDictionary<Element.ID, Element> = [:]
var count: Int {
_elements.count
}
var isEmpty: Bool {
_elements.isEmpty
}
var elements: [Element] {
Array(_elements.values)
}
@discardableResult
mutating func insert(_ element: Element) -> (inserted: Bool, memberAfterInsert: Element) {
if _elements.keys.contains(element.id) {
return (false, _elements[element.id]!)
} else {
_elements[element.id] = element
return (true, element)
}
}
@discardableResult
mutating func update(with newMember: Element) -> Element? {
let oldMember = _elements[newMember.id]
_elements[newMember.id] = newMember
return oldMember
}
@discardableResult
mutating func remove(_ member: Element) -> Element? {
return _elements.removeValue(forKey: member.id)
}
func contains(_ element: Element) -> Bool {
_elements.keys.contains(element.id)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment