Skip to content

Commit 1a56315

Browse files
authored
Merge pull request #10 from jVirus/astemir-mutablecollection-extension
Extension for MutableCollection
2 parents 7336581 + 560c17b commit 1a56315

File tree

1 file changed

+95
-0
lines changed
  • Sources/SwiftBoost/Foundation/Extensions

1 file changed

+95
-0
lines changed
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
import Foundation
2+
3+
/// This extension provides additional sorting capabilities for mutable collections that also conform to `RandomAccessCollection`.
4+
///
5+
/// These extension methods allow for easy sorting of collections where the elements have Comparable properties.
6+
///
7+
/// Example:
8+
///
9+
/// ```swift
10+
/// struct Person {
11+
/// let name: String
12+
/// let age: Int
13+
/// }
14+
///
15+
/// var people = [
16+
/// Person(name: "Alice", age: 30),
17+
/// Person(name: "Bob", age: 20),
18+
/// Person(name: "Charlie", age: 25)
19+
/// ]
20+
///
21+
/// // Sort by name in ascending order.
22+
/// let sortedByName = people.sorted(by: \.name, order: .ascending)
23+
///
24+
/// // Sort by age in descending order.
25+
/// let sortedByAge = people.sorted(by: \.age, order: .descending)
26+
///
27+
/// // Custom sort: sort by name length.
28+
/// let sortedByNameLength = people.sorted(by: \.name) { name1, name2 in
29+
/// return name1.count < name2.count
30+
/// }
31+
/// ```
32+
///
33+
/// - Note: These functions use Swift's `keyPath` feature to determine which property to sort by.
34+
public extension MutableCollection where Self: RandomAccessCollection {
35+
36+
/// Sorts the elements of the collection in the order specified by a closure that compares elements by a key path.
37+
///
38+
/// - Parameters:
39+
/// - keyPath: A key path to a comparable value on which to sort the collection's elements.
40+
/// - valuesAreInIncreasingOrder: A closure that takes two arguments and returns `true` if the first value should appear before the second in the sorted sequence, and `false` otherwise.
41+
/// - Returns: An array of the collection's elements sorted by the provided key path and comparison closure.
42+
func sorted<Value>(
43+
by keyPath: KeyPath<Element, Value>,
44+
using valuesAreInIncreasingOrder: (Value, Value) throws -> Bool
45+
) rethrows -> [Element] {
46+
try sorted {
47+
try valuesAreInIncreasingOrder($0[keyPath: keyPath], $1[keyPath: keyPath])
48+
}
49+
}
50+
51+
/// Sorts the elements of the collection in the order specified by a `MutableCollectionOrder` instance and a key path.
52+
///
53+
/// - Parameters:
54+
/// - keyPath: A key path to a comparable value on which to sort the collection's elements.
55+
/// - order: A `MutableCollectionOrder` instance specifying the order in which to sort the elements.
56+
/// - Returns: An array of the collection's elements sorted by the provided key path and order.
57+
func sorted<Value: Comparable>(
58+
by keyPath: KeyPath<Element, Value>,
59+
order: MutableCollectionOrder<Value>
60+
) -> [Element] {
61+
sorted(by: keyPath, using: order.operator)
62+
}
63+
}
64+
65+
// MARK: - Helper Utlity Type
66+
67+
/// `MutableCollectionOrder` is an enumeration representing the ordering options for collections of `Comparable` values.
68+
///
69+
/// This enum has two cases: `.ascending` and `.descending`, representing ascending and descending order respectively.
70+
///
71+
/// - Note:
72+
/// You can retrieve the associated comparison operator function for each case by accessing the `.operator` property.
73+
/// This operator function can be used to compare `Value` instances in a way that corresponds to the specified order.
74+
public enum MutableCollectionOrder<Value: Comparable> {
75+
76+
// MARK: - Cases
77+
78+
/// Represents ascending order. In this case, the associated operator function is `<`.
79+
case ascending
80+
/// Represents descending order. In this case, the associated operator function is `>`.
81+
case descending
82+
83+
// MARK: - Properties
84+
85+
/// Returns a comparison operator function corresponding to the order represented by the case.
86+
/// For `.ascending`, this function is `<`. For `.descending`, it's `>`.
87+
public var `operator`: (Value, Value) -> Bool {
88+
switch self {
89+
case .ascending:
90+
return (<)
91+
case .descending:
92+
return (>)
93+
}
94+
}
95+
}

0 commit comments

Comments
 (0)