Skip to content

Light revisions to guides #127

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Apr 13, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 19 additions & 11 deletions Guides/Compacted.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,37 +3,45 @@
[[Source](https://github.com/apple/swift-algorithms/blob/main/Sources/Algorithms/Compacted.swift) |
[Tests](https://github.com/apple/swift-algorithms/blob/main/Tests/SwiftAlgorithmsTests/CompactedTests.swift)]

Convenience method that flatten the `nil`s out of a sequence or collection.
That behaves exactly one of the most common uses of `compactMap` which is `collection.lazy.compactMap { $0 }`
which is only remove `nil`s without transforming the elements.
A convenience method that lazily flattens the `nil`s out of a sequence
or collection.

The new method matches one of the most common uses of `compactMap`,
which is to only remove `nil`s without transforming the elements
(e.g. `collection.lazy.compactMap { $0 }`).

```swift
let array: [Int?] = [10, nil, 30, nil, 2, 3, nil, 5]
let withNoNils = array.compacted()
// Array(withNoNils) == [10, 30, 2, 3, 5]

```

The most convenient part of `compacted()` is that we avoid the usage of a closure.
The type returned by `compacted()` lazily computes the non-`nil` elements
without requiring a user to provide a closure or use the `.lazy` property.

## Detailed Design

The `compacted()` methods has two overloads:

```swift
extension Sequence {
public func compacted<Unwrapped>() -> CompactedSequence<Self, Unwrapped> { ... }
public func compacted<Unwrapped>() -> CompactedSequence<Self, Unwrapped>
where Element == Unwrapped?
}

extension Collection {
public func compacted<Unwrapped>() -> CompactedCollection<Self, Unwrapped> { ... }
public func compacted<Unwrapped>() -> CompactedCollection<Self, Unwrapped>
where Element == Unwrapped?
}
```

One is a more general `CompactedSequence` for any `Sequence` base. And the other a more specialized `CompactedCollection`
where base is a `Collection` and with conditional conformance to `BidirectionalCollection`, `RandomAccessCollection` and
`LazyCollectionProtocol` when base collection conforms to them.
The `Sequence` version of `compacted()` returns a `CompactedSequence` type,
while the `Collection` version returns `CompactedCollection`. The collection
has conditional conformance to `BidirectionalCollection` and
`LazyCollectionProtocol` when the base collection conforms.

### Naming

The naming method name `compacted()` matches the current method `compactMap` that one of the most common usages `compactMap { $0 }` is abstracted by it.
The name `compacted()` matches the existing method `compactMap`,
which is commonly used to extract only the non-`nil` values
without mapping them to a different type.
9 changes: 5 additions & 4 deletions Guides/Cycle.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ for x in (1...3).cycled(times: 3) {
```

`cycled(times:)` provides a more expressive way of repeating a
collection's elements a limited number of times.
collection's elements a limited number of times than
combining `repeatElement(_:count:)` and `joined()`.

## Detailed Design

Expand All @@ -35,8 +36,8 @@ The new `Cycle` type is a sequence only, given that the `Collection` protocol
design makes infinitely large types impossible/impractical. `Cycle` also
conforms to `LazySequenceProtocol` when the base type conforms.

Note that the returned `FiniteCycle` will always have `Collection`
conformance, and will have `BidirectionalCollection` conformance
The `FiniteCycle` type always has `Collection` conformance, with
`BidirectionalCollection` conformance
when called on a bidirectional collection. `FiniteCycle` also
conforms to `LazyCollectionProtocol` when the base type conforms.

Expand All @@ -61,4 +62,4 @@ anything that matches the `cycled(times:)` behavior.
`cycled(times:)` here.

**Python:** Python’s `itertools` includes a `cycle` method, which caches the
elements of the iterator on the first pass.
elements of the iterator on the first pass.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ Read more about the package, and the intent behind it, in the [announcement on s

#### Subsetting operations

- [`compacted()`](https://github.com/apple/swift-algorithms/blob/main/Guides/Compacted.md): Drops the `nil`s from a sequence or collection, unwrapping the remaining elements.
- [`randomSample(count:)`, `randomSample(count:using:)`](https://github.com/apple/swift-algorithms/blob/main/Guides/RandomSampling.md): Randomly selects a specific number of elements from a collection.
- [`randomStableSample(count:)`, `randomStableSample(count:using:)`](https://github.com/apple/swift-algorithms/blob/main/Guides/RandomSampling.md): Randomly selects a specific number of elements from a collection, preserving their original relative order.
- [`striding(by:)`](https://github.com/apple/swift-algorithms/blob/main/Guides/Stride.md): Returns every nth element of a collection.
Expand All @@ -45,7 +46,6 @@ Read more about the package, and the intent behind it, in the [announcement on s
- [`reductions(_:)`, `reductions(_:_:)`](https://github.com/apple/swift-algorithms/blob/main/Guides/Reductions.md): Returns all the intermediate states of reducing the elements of a sequence or collection.
- [`split(maxSplits:omittingEmptySubsequences:whereSeparator)`, `split(separator:maxSplits:omittingEmptySubsequences)`](https://github.com/apple/swift-algorithms/blob/main/Guides/LazySplit.md): Lazy versions of the Standard Library's eager operations that split sequences and collections into subsequences separated by the specified separator element.
- [`windows(ofCount:)`](https://github.com/apple/swift-algorithms/blob/main/Guides/Windows.md): Breaks a collection into overlapping subsequences where elements are slices from the original collection.
- [`compacted()`](https://github.com/apple/swift-algorithms/blob/main/Guides/Compacted.md): Flatten the `nil`s out of a sequence or collection.

## Adding Swift Algorithms as a Dependency

Expand Down