Swiftpack.co - frazer-rbsn/OrderedSet as Swift Package

Swiftpack.co is a collection of thousands of indexed Swift packages. Search packages.
frazer-rbsn/OrderedSet
A simple, static Ordered Set collection type for Swift. Doesn't depend on Foundation.
.package(url: "https://github.com/frazer-rbsn/OrderedSet.git", from: "1.1.3")

OrderedSet

A static, ordered collection of unique objects.

macOS Ubuntu

About

In short, an OrderedSet is an immutable hybrid of an Array and a Set. Like an Array, it's elements have a defined order, but it enforces uniqueness on it's members like a Set.

You can use OrderedSet as a drop-in replacement for an Array if:

  • the element type conforms to Hashable (e.g. Int, String, Double etc., or your own type),
  • you do not need to perform in-place modification of the array,
  • and all elements should occur only once.

It can give you significant performance boosts when working with large collections, over using an Array.

You can use OrderedSet as a drop-in replacement for a Set if:

  • you do not need to perform in-place modification of the set,
  • and you require the members of the set to have a defined order.

OrderedSet is implemented in pure Swift with no Objective-C constructs. OrderedSet is a static set, i.e. once initialised, it cannot be mutated. It is similar to NSOrderedSet from Objective-C Foundation. OrderedSet has no dependencies. It does not depend on Foundation.

Installation

Swift Package Manager:

dependencies: [
  .package(url: "https://github.com/frazer-rbsn/OrderedSet.git", from: "1.1.0"),
],

Usage

For example, if we have a large array of strings, and we know that every string in this array should be unique:

let largeCollection: [String]

We can easily change this to an OrderedSet like this:

let largeCollection: OrderedSet<String>

The benefits of doing this can be seen when performing operations such as .contains(:_) on large collections, which on an OrderedSet, is an O(1) operation, as it's backed by a standard Set. On an array, this operation would be O(n), as the time required to compute it is affected by the number of items in the array.

Initialisation

An OrderedSet can be initialised in the following ways:

// With an array
let s = OrderedSet(["John", "Sally", "Bob", "Alice"])

// With a range
let s = OrderedSet(0..<5)
// ---> OrderedSet([0,1,2,3,4])

// With an array literal
let t : OrderedSet<String> = ["A", "B", "C"]

// With a set, sorted by a closure
let s = OrderedSet(someSet, sortedBy: { $0.name < $1.name })

// With a set, where the elements conform to Comparable
let comparableSet = Set([3,4,1,2])
let s = OrderedSet(comparableSet)
// ---> OrderedSet([1,2,3,4])

When initialising an OrderedSet with an array, by default the OrderedSet will retain the first instance of any duplicate elements:

let arr = ["Chris", "Bob", "Chris", "Alice"]
let s = OrderedSet(arr)
// ---> OrderedSet(["Chris", "Bob", "Alice"])

If you wish to retain the last occurrence of an element, use the retainLastOccurrences parameter and set it to true:

let arr = ["Chris", "Bob", "Chris", "Alice"]
let s = OrderedSet(arr, retainLastOccurrences: true)
// ---> OrderedSet(["Bob", "Chris", "Alice"])

Properties

When working with an OrderedSet, you may need to cast it back to an Array or Set when working with an API. OrderedSet provides access to it's internal storage via these properties:

  • .array
  • .contiguousArray
  • .unorderedSet

Functions

OrderedSet implements many of the common collection functions, such as compactMap(:_), filter(:_) and shuffled(:_). These will return a new OrderedSet instead of an array where possible.

let s = OrderedSet(["john", "sally", "bob", "alice"])
let t = s.map { $0.capitalized }
// ---> OrderedSet(["John", "Sally", "Bob", "Alice"])

Because OrderedSet is static -- it has no operations that can modify the collection --
it provides a few non-standard functions, such as removingAll(:_) which gives the inverse of an equivalent call to filter(:_), and appending(:_), which returns a new OrderedSet with the given element appended to the end.

Standard set algebra functions are available, and can be used with both other OrderedSet instances and standard Set collections.

let a = Set(1,2,4)
let b = OrderedSet([1,2,3,4,5])
let isSuperSet = b.isSuperset(of: a)
// ---> true

Unlike with an Array, checking the index of an element in OrderedSet is also an O(1) operation.

let s = OrderedSet(["Carol", "Bob", "Joan"])
let i = s.index(of: "Bob")
// ---> 1

Conformances

  • ExpressibleByArrayLiteral
  • RandomAccessCollection
  • Hashable
  • Equatable
  • Codable (if Element conforms to Codable)
  • CustomStringConvertible

OrderedSet will encode to and decode from a JSON array.

struct House: Codable {
  let members: OrderedSet<String>
}

let json = """
    {
      "members": [
        "Jim",
        "Carol",
        "Joan",
        "Felix"
      ]
    }
    """
let jsonData = json.data(using: .utf8)!
let decoder = JSONDecoder()
let house = try decoder.decode(House.self, from: jsonData)
// ---> house.members -> OrderedSet(["Jim","Carol","Joan","Felix"])

Equality is determined in the same way as an array.

let array = [1,2,3,4,5]
let array2 = [1,3,2,4,5]
let s1 = OrderedSet(array)
let s2 = OrderedSet(array2)
let isEqual = s1 == s2
// ---> false

License

MIT. See LICENSE.

GitHub

link
Stars: 1
Last commit: 3 weeks ago

Ad: Job Offers

iOS Software Engineer @ Perry Street Software
Perry Street Software is Jack’d and SCRUFF. We are two of the world’s largest gay, bi, trans and queer social dating apps on iOS and Android. Our brands reach more than 20 million members worldwide so members can connect, meet and express themselves on a platform that prioritizes privacy and security. We invest heavily into SwiftUI and using Swift Packages to modularize the codebase.

Submit a free job ad (while I'm testing this). The analytics numbers for this website are here.

Release Notes

1.1.3
8 weeks ago

Added function for calling SwiftUI's move(fromOffsets:_, toOffset:_) method on the collection.

Swiftpack is being maintained by Petr Pavlik | @ptrpavlik | @swiftpackco | API | Analytics