A high-performance, zero-dependency, pure Swift 6 algorithms and data structures library for iOS, macOS, watchOS, tvOS, and visionOS.
AlgorithmKit unifies the best algorithmic capabilities inspired by Apple's open-source packages (swift-algorithms, swift-collections) into a single, lightweight, declarative, and production-ready library.
Designed specifically for everyday Swift and SwiftUI developers who need high-performance operations without boilerplate or multi-package dependency sprawl.
| Module | What's Included | Primary Time Complexity |
|---|---|---|
| Collections |
Heap<T> (Min/Max Priority Queue), Deque<T> (Double-ended queue), OrderedSet<T>
|
|
| Sorting | Declarative KeyPath sorted(by:), TopK / BottomK ($O(N \log K)$), BinarySearch
|
|
| Filtering | Type-safe FilterBuilder DSL, stable uniqued(), grouped(by:), frequencies(by:)
|
|
| Search |
fuzzyMatches(_:), scoring with word-boundary/CamelCase bonuses, highlight ranges |
Subsequence scan with character range extraction |
| Chunking |
chunks(ofCount:), windows(ofCount:), interspersed(with:), moving averages |
|
Add AlgorithmKit to your Package.swift:
dependencies: [
.package(url: "https://github.com/nilkanthdesai/AlgorithmKit.git", from: "1.0.0")
]Or in Xcode:
- File β Add Package Dependencies...
- Enter the repository URL or local path.
- Select
AlgorithmKit.
Sort complex data models by multiple properties declaratively without nested ternary statements.
import AlgorithmKit
struct Employee {
let name: String
let department: String
let salary: Double
let rating: Double?
}
// Multi-field sort with custom nil handling:
let sortedStaff = employees.sorted(by: [
.ascending(\.department),
.descending(\.salary),
.ascending(\.rating, nulls: .last)
])Finding the top 10 items in a 1,000,000-item array usually requires an expensive AlgorithmKit uses a bounded binary heap to compute top-$K$ in
let top10Earners = employees.topK(10, by: \.salary)
let lowest3Prices = products.bottomK(3, by: \.price)Supercharge lookups on pre-sorted arrays with
let scores = [10, 20, 30, 40, 50, 60, 70]
// O(log N) exact binary search
if let index = scores.binarySearch(for: 40) {
print("Found at index \(index)")
}
// Partition point / Lower bound
let insertionPoint = scores.partitionPoint { $0 >= 35 } // Index 3 (value 40)Standard Set deduplication shuffles your array order. uniqued() retains the first occurrence order in
let tags = ["swift", "ios", "swift", "ui", "ios", "concurrency"]
let uniqueTags = tags.uniqued()
// ["swift", "ios", "ui", "concurrency"]
// Unique by KeyPath:
let uniqueUsers = users.uniqued(by: \.id)Compose expressive, readable filters for list rendering and search queries:
let filteredProducts = products.filter(
all(
.greaterThan(\.price, 20.0),
.lessThanOrEqual(\.price, 150.0),
.equals(\.inStock, true),
.stringContains(\.title, "Pro", caseSensitive: false)
)
)Transform sequences into dictionaries in a single readable step:
// Group items into dictionary of arrays:
let employeesByDept = employees.grouped(by: \.department)
// Count frequencies of values:
let voteCounts = ballots.frequencies()
// ["Alice": 1420, "Bob": 1105, "Charlie": 98]Built-in subsequence scoring engine with bonuses for consecutive matches, CamelCase transitions, and word boundaries. Returns matched character ranges for SwiftUI text highlighting:
if let match = "SettingsSecurityView".fuzzyMatch(query: "secview") {
print("Score: \(match.score)") // e.g. 0.85
// Use match.matchedRanges in SwiftUI Text to bold matched letters!
}
// Filter and rank an array by relevance:
let searchResults = viewNames.fuzzySearch(query: "prof")Easily paginate or batch items for network requests, or calculate moving averages:
// Fixed-size chunking (e.g., batch uploads)
let batches = [1, 2, 3, 4, 5, 6, 7, 8].chunks(ofCount: 3)
// [[1, 2, 3], [4, 5, 6], [7, 8]]
// Sliding windows (e.g., rolling stock analysis)
let rollingWindows = [1, 2, 3, 4, 5].windows(ofCount: 3)
// [[1, 2, 3], [2, 3, 4], [3, 4, 5]]
// Interspersing separators (e.g., list dividers)
let breadcrumbs = ["Home", "Products", "Electronics"].interspersed(with: " > ")
// ["Home", " > ", "Products", " > ", "Electronics"]Min-Heap or Max-Heap backed by a flat contiguous array with
var taskQueue = Heap<Task>.minHeap(by: \.priority)
taskQueue.insert(Task(title: "Urgent bug", priority: 1))
taskQueue.insert(Task(title: "Documentation", priority: 5))
let nextTask = taskQueue.pop() // Priority 1Ring buffer with Array.removeFirst().
var deque = Deque<Int>()
deque.append(10)
deque.prepend(5)
let first = deque.popFirst() // 5 in O(1)
let last = deque.popLast() // 10 in O(1)Maintains strict insertion order while ensuring all elements are unique and providing contains lookups.
var recentSearches = OrderedSet<String>()
recentSearches.append("Swift 6")
recentSearches.append("SwiftUI")
recentSearches.append("Swift 6") // Ignored - already present
print(recentSearches.elements) // ["Swift 6", "SwiftUI"]- Fully compliant with Swift 6 Strict Concurrency (
Sendableaudited). - Heavy use of
@inlinableand specialized generic constraints for zero-overhead performance matching native hand-written loops. - 100% test coverage with zero warnings.
MIT License. Feel free to use in personal, open-source, or commercial iOS/macOS projects.