DandyLyons/KindaSortaEqual
Swift convenience APIs for values that are kind of, sort of equal.
Overview
Many comparisons don't require strict, bit-for-bit equality. This package provides helpers to express common "close enough" equality checks in a clear, testable way.
Key concepts
hasSameElements(as:)— compare two collections for equality while ignoring element order.AlmostEquatable— a protocol for types that can be compared within a threshold (tolerance).SelectiveEquatable— a protocol (from the SelectiveEquatable package) where equality is performed only on the provided key paths.- equivalence (experimental):
SelectiveEquatablepackage vends a set ofisEquivalent(to:). These compare two collections, ignore order, and verify that each collection has exactly one element with a matching id and other values.
Installation
Add the package to your Package.swift dependencies:
.package(url: "https://github.com/yourusername/KindaSortaEqual.git", from: "0.1.0"),Then add the product to your target dependencies.
Usage
Below are short examples for the main paradigms. They assume the helpers are exported from the KindaSortaEqual module.
Unordered collection equality
Use hasSameElements(as:) to check two collections contain the same elements regardless of order. This is useful when element order is not meaningful.
import KindaSortaEqual
let a = [1, 2, 3]
let b = [3, 1, 2]
let c = [1, 2, 3, 3]
a.hasSameElements(as: b) // true
a.hasSameElements(as: c) // falseTo count as true, both collections must contain the same elements with the same multiplicity. The order of elements does not matter.
AlmostEquatable protocol
AlmostEquatable is a lightweight protocol used to express that two values are "close" by some measure (for example, within a tolerance for floating point values). Types conforming to AlmostEquatable implement a method such as isAlmostEqual(to:threshold:).
import KindaSortaEqual
extension Double: AlmostEquatable {
func isAlmostEqual(to other: Double, threshold: Double = 1e-8) -> Bool {
return abs(self - other) <= threshold
}
}
let x: Double = 0.30000000000000004
let y: Double = 0.3
print(x.isAlmostEqual(to: y, threshold: 1e-12))The package includes conformances and helpers for arrays, floating point types, CoreGraphics types, and some common custom types—see the Sources/KindaSortaEqual/AlmostEquatable folder for concrete implementations and tests.
The library comes with several built-in conformances for common types including:
Double,FloatCGPoint,CGSize,CGRectDateArrayUIColor,NSColor
SelectiveEquatable protocol
SelectiveEquatable (from the SelectiveEquatable package) lets you state equality in terms of a set of key paths. Provide the key paths you care about and equality will be checked only for those properties.
Refer to the Sources/KindaSortaEqual/SelectiveEquatable.swift for the exact API surface used by this package.
Conforming to SelectiveEquatable is as simple as:
extension MyType: SelectiveEquatable {}That's it. No methods need to be implemented. If you have any equatable properties then you can instantly benefit from SelectiveEquatable.
let person1 = Person(name: "Alice", age: 30, address: "123 Main St")
let person2 = Person(name: "Alice", age: 30, address: "456 Elm St")
person1.isEqual(to: person2, by: \.name, \.age) // trueOther Approaches
Be sure to check out Uncertain<T> by Mattt which has some similar ideas but is solving a fundamentally different problem.
Contributing
Contributions are welcome. Please open issues or PRs. Keep changes small and focused. Add tests for new behavior.
License
Licensed by the MIT License. This repository includes a LICENSE file—please refer to it for licensing information.
Package Metadata
Repository: DandyLyons/KindaSortaEqual
Stars: 0
Forks: 0
Open issues: 0
Default branch: main
Primary language: swift
License: MIT
README: README.md