From 4190dec46fc7db40d3d6e19e82bfb7d279897026 Mon Sep 17 00:00:00 2001
From: Dmitriy Ignatyev <>
Date: Wed, 10 Jan 2024 05:36:05 +0300
Subject: [PATCH 1/6] added partitionMap
---
Sources/Algorithms/PartitionMap.swift | 203 ++++++++++++++++++++++++++
1 file changed, 203 insertions(+)
create mode 100644 Sources/Algorithms/PartitionMap.swift
diff --git a/Sources/Algorithms/PartitionMap.swift b/Sources/Algorithms/PartitionMap.swift
new file mode 100644
index 00000000..a7b40677
--- /dev/null
+++ b/Sources/Algorithms/PartitionMap.swift
@@ -0,0 +1,203 @@
+//===----------------------------------------------------------------------===//
+//
+// This source file is part of the Swift Algorithms open source project
+//
+// Copyright (c) 2020-2023 Apple Inc. and the Swift project authors
+// Licensed under Apache License v2.0 with Runtime Library Exception
+//
+// See https://swift.org/LICENSE.txt for license information
+//
+//===----------------------------------------------------------------------===//
+
+//===----------------------------------------------------------------------===//
+// PartitionMapResult2
+//===----------------------------------------------------------------------===//
+
+// `PartitionMapResult` Types are needed because of current generic limitations.
+// It is separated into public struct and internal enum. Such design has benefits
+// in comparison to plain enum:
+// - prevent its usage as a general purpose Either / OneOf Type – there are no
+// public properties which makes it useless outside
+// the library anywhere except with `partitionMap()` function.
+// - allows to rename `first`, `second` and `third` without source breakage .
+// If something more suitable will be found then old static initializers can be
+// deprecated with introducing new ones.
+
+public struct PartitionMapResult2 {
+ @usableFromInline
+ internal let oneOf: _PartitionMapResult2
+
+ @usableFromInline
+ internal init(oneOf: _PartitionMapResult2) { self.oneOf = oneOf }
+
+ @inlinable
+ public static func first(_ value: A) -> Self {
+ Self(oneOf: .first(value))
+ }
+
+ @inlinable
+ public static func second(_ value: B) -> Self {
+ Self(oneOf: .second(value))
+ }
+}
+
+@usableFromInline
+internal enum _PartitionMapResult2 {
+ case first(A)
+ case second(B)
+}
+
+//===----------------------------------------------------------------------===//
+// PartitionMapResult3
+//===----------------------------------------------------------------------===//
+
+public struct PartitionMapResult3 {
+ @usableFromInline
+ internal let oneOf: _PartitionMapResult3
+
+ @usableFromInline
+ internal init(oneOf: _PartitionMapResult3) {
+ self.oneOf = oneOf
+ }
+
+ @inlinable
+ public static func first(_ value: A) -> Self {
+ Self(oneOf: .first(value))
+ }
+
+ @inlinable
+ public static func second(_ value: B) -> Self {
+ Self(oneOf: .second(value))
+ }
+
+ @inlinable
+ public static func third(_ value: C) -> Self {
+ Self(oneOf: .third(value))
+ }
+}
+
+@usableFromInline
+internal enum _PartitionMapResult3 {
+ case first(A)
+ case second(B)
+ case third(C)
+}
+
+//===----------------------------------------------------------------------===//
+// partitionMap()
+//===----------------------------------------------------------------------===//
+
+extension Sequence {
+ /// Allows to separate elements into distinct groups while applying a transformation to each element
+ ///
+ /// This method do the same as `partitioned(by:)` but with an added map step baked in for
+ /// ergonomic reasons.
+ ///
+ /// The `partitionMap` applies the given closure to each element of the collection and divides the
+ /// results into two groups based on the transformation's output.
+ /// The closure returns a `PartitionMapResult`, which indicates whether the result should be
+ /// included in the first group or in the second.
+ ///
+ /// In this example, `partitionMap(_:)` is used to separate an array of `any Error` elements into
+ /// two arrays while also transforming the type from
+ /// `any Error` to `URLSessionError` for the first group.
+ /// ```
+ /// func handle(errors: [any Error]) {
+ /// let (recoverableErrors, unrecoverableErrors) = errors
+ /// .partitionMap { error -> PartitionMapResult2 in
+ /// switch error {
+ /// case let urlError as URLSessionError: return .first(urlError)
+ /// default: return .second(error)
+ /// }
+ /// }
+ /// // recoverableErrors Type is Array
+ /// // unrecoverableErrors Type is Array
+ /// }
+ /// ```
+ ///
+ /// - Parameters:
+ /// - transform: A mapping closure. `transform` accepts an element of this sequence as its
+ /// parameter and returns a `PartitionMapResult` with a transformed value, representing
+ /// membership to either the first or second group with elements of the original or of a different type.
+ ///
+ /// - Returns: Two arrays, with elements from the first or second group appropriately.
+ ///
+ /// - Throws: Rethrows any errors produced by the `transform` closure.
+ ///
+ /// - Complexity: O(*n*), where *n* is the length of the collection.
+ @inlinable
+ public func partitionMap(
+ _ transform: (Element) throws -> PartitionMapResult2
+ ) rethrows -> ([A], [B]) {
+ var groupA: [A] = []
+ var groupB: [B] = []
+
+ for element in self {
+ switch try transform(element).oneOf {
+ case .first(let a): groupA.append(a)
+ case .second(let b): groupB.append(b)
+ }
+ }
+
+ return (groupA, groupB)
+ }
+
+ /// Allows to separate elements into distinct groups while applying a transformation to each element
+ ///
+ /// This method do the same as `partitioned(by:)` but with an added map step baked in for
+ /// ergonomic reasons.
+ ///
+ /// The `partitionMap` applies the given closure to each element of the collection and divides the
+ /// results into distinct groups based on the transformation's output.
+ /// The closure returns a `PartitionMapResult`, which indicates whether the result should be
+ /// included in the first , second or third group.
+ ///
+ /// In this example, `partitionMap(_:)` is used to separate an array of `any Error` elements into
+ /// three arrays while also transforming the type from
+ /// `any Error` to `URLSessionError` for the first and second groups.
+ /// ```
+ /// func handle(errors: [any Error]) {
+ /// let (recoverableErrors, unrecoverableErrors, unknownErrors) = errors
+ /// .partitionMap { error -> PartitionMapResult3 in
+ /// switch error {
+ /// case let urlError as URLSessionError:
+ /// return recoverableURLErrorCodes.contains(urlError.code) ? .first(urlError) : .second(urlError)
+ /// default:
+ /// return .third(error)
+ /// }
+ /// }
+ /// // recoverableErrors Type is Array
+ /// // unrecoverableErrors Type is Array
+ /// // unknownErrors Type is Array
+ /// }
+ /// ```
+ ///
+ /// - Parameters:
+ /// - transform: A mapping closure. `transform` accepts an element of this sequence as its
+ /// parameter and returns a `PartitionMapResult` with a transformed value, representing
+ /// membership to either first, second or third group with elements of the original or of a different type.
+ ///
+ /// - Returns: Three arrays, with elements from the first, second or third group appropriately.
+ ///
+ /// - Throws: Rethrows any errors produced by the `transform` closure.
+ ///
+ /// - Complexity: O(*n*), where *n* is the length of the collection.
+ @inlinable
+ public func partitionMap(
+ _ transform: (Element) throws -> PartitionMapResult3
+ ) rethrows -> ([A], [B], [C]) {
+ var groupA: [A] = []
+ var groupB: [B] = []
+ var groupC: [C] = []
+
+ for element in self {
+ switch try transform(element).oneOf {
+ case .first(let a): groupA.append(a)
+ case .second(let b): groupB.append(b)
+ case .third(let c): groupC.append(c)
+ }
+ }
+
+ return (groupA, groupB, groupC)
+ }
+}
From b49f41f383b6a752d67f4d1784b5f4bfbba236e3 Mon Sep 17 00:00:00 2001
From: Dmitriy Ignatyev <>
Date: Wed, 17 Jan 2024 00:49:30 +0300
Subject: [PATCH 2/6] add `partitionMap(_:)` tests (+1 squashed commit)
Squashed commits: [6dcee60] add `partitionMap(_:)` tests
---
Sources/Algorithms/PartitionMap.swift | 8 +-
.../PartitionMapTests.swift | 148 ++++++++++++++++++
2 files changed, 153 insertions(+), 3 deletions(-)
create mode 100644 Tests/SwiftAlgorithmsTests/PartitionMapTests.swift
diff --git a/Sources/Algorithms/PartitionMap.swift b/Sources/Algorithms/PartitionMap.swift
index a7b40677..7da0706e 100644
--- a/Sources/Algorithms/PartitionMap.swift
+++ b/Sources/Algorithms/PartitionMap.swift
@@ -27,8 +27,10 @@ public struct PartitionMapResult2 {
@usableFromInline
internal let oneOf: _PartitionMapResult2
- @usableFromInline
- internal init(oneOf: _PartitionMapResult2) { self.oneOf = oneOf }
+ @inlinable
+ internal init(oneOf: _PartitionMapResult2) {
+ self.oneOf = oneOf
+ }
@inlinable
public static func first(_ value: A) -> Self {
@@ -55,7 +57,7 @@ public struct PartitionMapResult3 {
@usableFromInline
internal let oneOf: _PartitionMapResult3
- @usableFromInline
+ @inlinable
internal init(oneOf: _PartitionMapResult3) {
self.oneOf = oneOf
}
diff --git a/Tests/SwiftAlgorithmsTests/PartitionMapTests.swift b/Tests/SwiftAlgorithmsTests/PartitionMapTests.swift
new file mode 100644
index 00000000..811d80e9
--- /dev/null
+++ b/Tests/SwiftAlgorithmsTests/PartitionMapTests.swift
@@ -0,0 +1,148 @@
+//===----------------------------------------------------------------------===//
+//
+// This source file is part of the Swift Algorithms open source project
+//
+// Copyright (c) 2023 Apple Inc. and the Swift project authors
+// Licensed under Apache License v2.0 with Runtime Library Exception
+//
+// See https://swift.org/LICENSE.txt for license information
+//
+//===----------------------------------------------------------------------===//
+
+import XCTest
+import Algorithms
+
+final class PartitionMapTests: XCTestCase {
+ func testPartitionMap2WithEmptyInput() {
+ let input: [Int] = []
+
+ let (first, second) = input.partitionMap { _ -> PartitionMapResult2 in
+ .first(0)
+ }
+
+ XCTAssertTrue(first.isEmpty)
+ XCTAssertTrue(second.isEmpty)
+ }
+
+ func testPartitionMap3WithEmptyInput() {
+ let input: [Int] = []
+
+ let (first, second, third) = input.partitionMap { _ -> PartitionMapResult3 in
+ .first(0)
+ }
+
+ XCTAssertTrue(first.isEmpty)
+ XCTAssertTrue(second.isEmpty)
+ XCTAssertTrue(third.isEmpty)
+ }
+
+ func testPartitionMap2Example() throws {
+ let nanString = String(describing: Double.nan)
+ let numericStrings = ["", "^", "-1", "0", "1", "-1.5", "1.5", nanString]
+
+ let (doubles, unrepresentable) = numericStrings
+ .partitionMap { string -> PartitionMapResult2 in
+ if let double = Double(string) {
+ return .first(double)
+ } else {
+ return .second(string)
+ }
+ }
+
+ XCTAssertEqual(doubles.map(String.init(describing:)), ["-1.0", "0.0", "1.0", "-1.5", "1.5", nanString])
+ XCTAssertEqual(unrepresentable, ["", "^"])
+ }
+
+ func testPartitionMap3Example() throws {
+ let nanString = String(describing: Double.nan)
+ let numericStrings = ["", "^", "-1", "0", "1", "-1.5", "1.5", nanString]
+
+ let (integers, doubles, unrepresentable) = numericStrings
+ .partitionMap { string -> PartitionMapResult3 in
+ if let integer = Int(string) {
+ return .first(integer)
+ } else if let double = Double(string) {
+ return .second(double)
+ } else {
+ return .third(string)
+ }
+ }
+
+ XCTAssertEqual(integers, [-1, 0, 1])
+ XCTAssertEqual(doubles.map(String.init(describing:)), ["-1.5", "1.5", nanString])
+ XCTAssertEqual(unrepresentable, ["", "^"])
+ }
+
+
+ func testPartitionMap2WithPredicate() throws {
+ let predicate: (Int) throws -> PartitionMapResult2 = { number -> PartitionMapResult2 in
+ if let uint = UInt8(exactly: number) {
+ return .second(uint)
+ } else if let int = Int8(exactly: number) {
+ return .first(int)
+ } else {
+ throw TestError()
+ }
+ }
+
+ let s0 = try [1, 2, 3, 4].partitionMap(predicate)
+ let s1 = try [-1, 2, 3, 4].partitionMap(predicate)
+ let s2 = try [-1, 2, -3, 4].partitionMap(predicate)
+ let s3 = try [-1, 2, -3, -4].partitionMap(predicate)
+
+ XCTAssertThrowsError(try [256].partitionMap(predicate))
+ XCTAssertThrowsError(try [-129].partitionMap(predicate))
+
+ XCTAssertEqual(s0.0, [])
+ XCTAssertEqual(s0.1, [1, 2, 3, 4])
+
+ XCTAssertEqual(s1.0, [-1])
+ XCTAssertEqual(s1.1, [2, 3, 4])
+
+ XCTAssertEqual(s2.0, [-1, -3])
+ XCTAssertEqual(s2.1, [2, 4])
+
+ XCTAssertEqual(s3.0, [-1, -3, -4])
+ XCTAssertEqual(s3.1, [2])
+ }
+
+ func testPartitionMap3WithPredicate() throws {
+ let predicate: (Int) throws -> PartitionMapResult3 = { number -> PartitionMapResult3 in
+ if number == 0 {
+ return .third(Void())
+ } else if let uint = UInt8(exactly: number) {
+ return .second(uint)
+ } else if let int = Int8(exactly: number) {
+ return .first(int)
+ } else {
+ throw TestError()
+ }
+ }
+
+ let s0 = try [0, 1, 2, 3, 4].partitionMap(predicate)
+ let s1 = try [0, 0, -1, 2, 3, 4].partitionMap(predicate)
+ let s2 = try [0, 0, -1, 2, -3, 4].partitionMap(predicate)
+ let s3 = try [0, -1, 2, -3, -4].partitionMap(predicate)
+
+ XCTAssertThrowsError(try [256].partitionMap(predicate))
+ XCTAssertThrowsError(try [-129].partitionMap(predicate))
+
+ XCTAssertEqual(s0.0, [])
+ XCTAssertEqual(s0.1, [1, 2, 3, 4])
+ XCTAssertEqual(s0.2.count, 1)
+
+ XCTAssertEqual(s1.0, [-1])
+ XCTAssertEqual(s1.1, [2, 3, 4])
+ XCTAssertEqual(s1.2.count, 2)
+
+ XCTAssertEqual(s2.0, [-1, -3])
+ XCTAssertEqual(s2.1, [2, 4])
+ XCTAssertEqual(s2.2.count, 2)
+
+ XCTAssertEqual(s3.0, [-1, -3, -4])
+ XCTAssertEqual(s3.1, [2])
+ XCTAssertEqual(s3.2.count, 1)
+ }
+
+ private struct TestError: Error {}
+}
From 9cf2276b1eca82de11ee3bca46aff270a70e3acd Mon Sep 17 00:00:00 2001
From: Dmitriy Ignatyev
Date: Wed, 16 Apr 2025 11:57:33 +0300
Subject: [PATCH 3/6] prepare for merge request
---
Guides/PartitionMap.md | 50 ++++++++++++++++
Sources/Algorithms/PartitionMap.swift | 82 ++++++++++++++++-----------
2 files changed, 99 insertions(+), 33 deletions(-)
create mode 100644 Guides/PartitionMap.md
diff --git a/Guides/PartitionMap.md b/Guides/PartitionMap.md
new file mode 100644
index 00000000..d814ef20
--- /dev/null
+++ b/Guides/PartitionMap.md
@@ -0,0 +1,50 @@
+# Grouped
+
+[[Source](https://github.com/apple/swift-algorithms/blob/main/Sources/Algorithms/PartitionMap.swift) |
+ [Tests](https://github.com/apple/swift-algorithms/blob/main/Tests/SwiftAlgorithmsTests/PartitionMapTests.swift)]
+
+Groups up elements of a sequence into two Arrays while applying a transform closure for each element.
+
+```swift
+func process(results: [Result]) {
+ let (successes, failures) = results
+ .partitionMap { result -> PartitionMapResult2 in
+ switch result {
+ case .success(let value): .first(value)
+ case .failure(let error): .second(error)
+ }
+ }
+}
+```
+
+It is similar to some other grouping functions, but achives another goals.
+- in comparison to `partitioned(by:)` it allows to make to make a transform for each element of the source sequence
+independently for groups. Also it is possible to make more then 2 groups.
+- in comparison to `grouped(by:)` & `split(whereSeparator:)` it has exact number of groups defined at compile time.
+For `grouped(by:)` & `split(whereSeparator:)` number of groups is dynamicaly defined while program executiin.
+
+## Detailed Design
+
+The `partitionMap(_:)` method is declared as a `Sequence` extension returning a tuple with 2 or 3 arrays.
+`([NewTypeA], [NewTypeB])`.
+
+```swift
+extension Sequence {
+ public func partitionMap(
+ _ transform: (Element) throws(Error) -> PartitionMapResult3
+ ) throws(Error) -> ([A], [B], [C])
+}
+```
+
+`PartitionMapResult` Types are needed because of current generic limitations.
+It is separated into public struct and internal enum. Such design has benefits
+in comparison to plain enum:
+- prevent its usage as a general purpose Either / OneOf Type – there are no
+public properties which makes it usable outside the library.
+- allows to rename `first`, `second` and `third` without source breakage.
+If something more suitable will be found in future then old static initializers can be
+deprecated with introducing new ones.
+
+### Complexity
+
+Calling `partitionMap(_:)` is an O(_n_) operation.
diff --git a/Sources/Algorithms/PartitionMap.swift b/Sources/Algorithms/PartitionMap.swift
index 7da0706e..52f42f9a 100644
--- a/Sources/Algorithms/PartitionMap.swift
+++ b/Sources/Algorithms/PartitionMap.swift
@@ -13,16 +13,6 @@
// PartitionMapResult2
//===----------------------------------------------------------------------===//
-// `PartitionMapResult` Types are needed because of current generic limitations.
-// It is separated into public struct and internal enum. Such design has benefits
-// in comparison to plain enum:
-// - prevent its usage as a general purpose Either / OneOf Type – there are no
-// public properties which makes it useless outside
-// the library anywhere except with `partitionMap()` function.
-// - allows to rename `first`, `second` and `third` without source breakage .
-// If something more suitable will be found then old static initializers can be
-// deprecated with introducing new ones.
-
public struct PartitionMapResult2 {
@usableFromInline
internal let oneOf: _PartitionMapResult2
@@ -100,20 +90,32 @@ extension Sequence {
/// The closure returns a `PartitionMapResult`, which indicates whether the result should be
/// included in the first group or in the second.
///
- /// In this example, `partitionMap(_:)` is used to separate an array of `any Error` elements into
- /// two arrays while also transforming the type from
- /// `any Error` to `URLSessionError` for the first group.
+ /// Example 1:
+ /// ```
+ /// func process(results: [Result]) {
+ /// let (successes, failures) = results
+ /// .partitionMap { result -> PartitionMapResult2 in
+ /// switch result {
+ /// case .success(let value): .first(value)
+ /// case .failure(let error): .second(error)
+ /// }
+ /// }
+ /// }
+ /// ```
+ /// Example 2:
+ /// `partitionMap(_:)` is used to separate an array of `any Error` elements into two arrays while
+ /// also transforming the type from `any Error` to `URLSessionError` for the first group.
/// ```
/// func handle(errors: [any Error]) {
- /// let (recoverableErrors, unrecoverableErrors) = errors
+ /// let (urlSessionErrors, unknownErrors) = errors
/// .partitionMap { error -> PartitionMapResult2 in
/// switch error {
- /// case let urlError as URLSessionError: return .first(urlError)
- /// default: return .second(error)
+ /// case let urlError as URLSessionError: .first(urlError)
+ /// default: .second(error)
/// }
/// }
- /// // recoverableErrors Type is Array
- /// // unrecoverableErrors Type is Array
+ /// // `urlSessionErrors` Type is `Array`
+ /// // `unknownErrors` Type is `Array`
/// }
/// ```
///
@@ -128,9 +130,9 @@ extension Sequence {
///
/// - Complexity: O(*n*), where *n* is the length of the collection.
@inlinable
- public func partitionMap(
- _ transform: (Element) throws -> PartitionMapResult2
- ) rethrows -> ([A], [B]) {
+ public func partitionMap(
+ _ transform: (Element) throws(Error) -> PartitionMapResult2
+ ) throws(Error) -> ([A], [B]) {
var groupA: [A] = []
var groupB: [B] = []
@@ -153,24 +155,38 @@ extension Sequence {
/// results into distinct groups based on the transformation's output.
/// The closure returns a `PartitionMapResult`, which indicates whether the result should be
/// included in the first , second or third group.
- ///
- /// In this example, `partitionMap(_:)` is used to separate an array of `any Error` elements into
- /// three arrays while also transforming the type from
+ /// - Example 1:
+ /// ```
+ /// func process(results: [Result]) {
+ /// let (successes, failures) = results
+ /// .partitionMap { result -> PartitionMapResult2 in
+ /// switch result {
+ /// case .success(let value): .first(value)
+ /// case .failure(let error): .second(error)
+ /// }
+ /// }
+ /// }
+ /// ```
+ /// - Example 2:
+ /// `partitionMap(_:)` is used to separate an array of `any Error` elements into three arrays
+ /// while also transforming the type from
/// `any Error` to `URLSessionError` for the first and second groups.
/// ```
/// func handle(errors: [any Error]) {
- /// let (recoverableErrors, unrecoverableErrors, unknownErrors) = errors
+ /// let (urlSessionErrors, httpErrors, unknownErrors) = errors
/// .partitionMap { error -> PartitionMapResult3 in
/// switch error {
/// case let urlError as URLSessionError:
- /// return recoverableURLErrorCodes.contains(urlError.code) ? .first(urlError) : .second(urlError)
+ /// .first(urlError)
+ /// case let httpError as HTTPError:
+ /// .second(urlError)
/// default:
- /// return .third(error)
+ /// .third(error)
/// }
/// }
- /// // recoverableErrors Type is Array
- /// // unrecoverableErrors Type is Array
- /// // unknownErrors Type is Array
+ /// // `urlSessionErrors` Type `is Array`
+ /// // `httpErrors` Type is `Array`
+ /// // `unknownErrors` Type is `Array`
/// }
/// ```
///
@@ -185,9 +201,9 @@ extension Sequence {
///
/// - Complexity: O(*n*), where *n* is the length of the collection.
@inlinable
- public func partitionMap(
- _ transform: (Element) throws -> PartitionMapResult3
- ) rethrows -> ([A], [B], [C]) {
+ public func partitionMap(
+ _ transform: (Element) throws(Error) -> PartitionMapResult3
+ ) throws(Error) -> ([A], [B], [C]) {
var groupA: [A] = []
var groupB: [B] = []
var groupC: [C] = []
From 0aac37fbe7221d5ed1bb793bbf6b9a78c0f9bf57 Mon Sep 17 00:00:00 2001
From: Dmitriy Ignatyev
Date: Wed, 16 Apr 2025 12:02:40 +0300
Subject: [PATCH 4/6] fix typo
---
Guides/PartitionMap.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Guides/PartitionMap.md b/Guides/PartitionMap.md
index d814ef20..db9fcc54 100644
--- a/Guides/PartitionMap.md
+++ b/Guides/PartitionMap.md
@@ -1,4 +1,4 @@
-# Grouped
+# PartitionMap
[[Source](https://github.com/apple/swift-algorithms/blob/main/Sources/Algorithms/PartitionMap.swift) |
[Tests](https://github.com/apple/swift-algorithms/blob/main/Tests/SwiftAlgorithmsTests/PartitionMapTests.swift)]
From 991d22a642df4d804f40a68341037029011b8a39 Mon Sep 17 00:00:00 2001
From: Dmitriy Ignatyev
Date: Wed, 16 Apr 2025 12:05:52 +0300
Subject: [PATCH 5/6] fix type
---
Guides/PartitionMap.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Guides/PartitionMap.md b/Guides/PartitionMap.md
index db9fcc54..3ee4fbf3 100644
--- a/Guides/PartitionMap.md
+++ b/Guides/PartitionMap.md
@@ -21,7 +21,7 @@ It is similar to some other grouping functions, but achives another goals.
- in comparison to `partitioned(by:)` it allows to make to make a transform for each element of the source sequence
independently for groups. Also it is possible to make more then 2 groups.
- in comparison to `grouped(by:)` & `split(whereSeparator:)` it has exact number of groups defined at compile time.
-For `grouped(by:)` & `split(whereSeparator:)` number of groups is dynamicaly defined while program executiin.
+For `grouped(by:)` & `split(whereSeparator:)` number of groups is dynamicaly defined while program execution.
## Detailed Design
From e51779ec9fc54516427467198cad3ad1982e35de Mon Sep 17 00:00:00 2001
From: Dmitriy Ignatyev
Date: Wed, 16 Apr 2025 16:23:15 +0300
Subject: [PATCH 6/6] comment added
---
Guides/PartitionMap.md | 1 +
1 file changed, 1 insertion(+)
diff --git a/Guides/PartitionMap.md b/Guides/PartitionMap.md
index 3ee4fbf3..6a781154 100644
--- a/Guides/PartitionMap.md
+++ b/Guides/PartitionMap.md
@@ -4,6 +4,7 @@
[Tests](https://github.com/apple/swift-algorithms/blob/main/Tests/SwiftAlgorithmsTests/PartitionMapTests.swift)]
Groups up elements of a sequence into two Arrays while applying a transform closure for each element.
+This method is a partition with an added map step baked in for ergonomic reasons.
```swift
func process(results: [Result]) {