Skip to content

Commit

Permalink
Initial import
Browse files Browse the repository at this point in the history
  • Loading branch information
natecook1000 committed Oct 7, 2020
0 parents commit 6cffd04
Show file tree
Hide file tree
Showing 47 changed files with 3,944 additions and 0 deletions.
33 changes: 33 additions & 0 deletions .github/ISSUE_TEMPLATE/BUG_REPORT.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
---
name: 🐛 Bug Report
about: Something isn't working as expected
---

<!--
Thanks for contributing to Swift Algorithms!
Before you submit your issue, please replace each paragraph
below with the relevant details for your bug, and complete
the steps in the checklist by placing an 'x' in each box:
- [x] I've completed this task
- [ ] This task isn't completed
-->

Replace this paragraph with a short description of the incorrect incorrect behavior. If this is a regression, please note the last version that the behavior was correct in addition to your current version.

**Swift Algorithms version:** `0.0.1` or the `main` branch, for example.
**Swift version:** Paste the output of `swift --version` here.

### Checklist
- [ ] If possible, I've reproduced the issue using the `main` branch of this package
- [ ] I've searched for [existing GitHub issues](https://github.com/apple/swift-algorithms/issues)

### Steps to Reproduce
Replace this paragraph with an explanation of how to reproduce the incorrect behavior. Include a simple code example, if possible.

### Expected behavior
Describe what you expect to happen.

### Actual behavior
Describe or copy/paste the behavior you observe.
13 changes: 13 additions & 0 deletions .github/ISSUE_TEMPLATE/FEATURE_REQUEST.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
---
name: 💡 Feature Request
about: A suggestion for a new feature
---

<!--
Thanks for contributing to Swift Algorithms!
Before you submit your issue, please replace the paragraph
below with information about your proposed feature.
-->

Replace this paragraph with a description of your proposed feature. Code samples that show what's missing, or what new capabilities will be possible, are very helpful! Provide links to existing issues or external references/discussions, if appropriate.
5 changes: 5 additions & 0 deletions .github/ISSUE_TEMPLATE/config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
blank_issues_enabled: false
contact_links:
- name: ❓ Discussion Forum
url: https://forums.swift.org/c/related-projects/algorithms/
about: Questions about using Swift Algorithms? Ask here!
21 changes: 21 additions & 0 deletions .github/PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<!--
Thanks for contributing to Swift Algorithms!
If this pull request adds new API, please add '?template=new.md'
to the URL to switch to the appropriate template.
Before you submit your request, please replace the paragraph
below with the relevant details, and complete the steps in the
checklist by placing an 'x' in each box:
- [x] I've completed this task
- [ ] This task isn't completed
-->

Replace this paragraph with a description of your changes and rationale. Provide links to an existing issue or external references/discussions, if appropriate.

### Checklist
- [ ] I've added at least one test that validates that my change is working, if appropriate
- [ ] I've followed the code style of the rest of the project
- [ ] I've read the [Contribution Guidelines](CONTRIBUTING.md)
- [ ] I've updated the documentation if necessary
38 changes: 38 additions & 0 deletions .github/PULL_REQUEST_TEMPLATE/NEW.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<!--
Thanks for contributing to Swift Algorithms!
Before you submit your request, please replace each paragraph
below with the relevant details, and complete the steps in the
checklist by placing an 'x' in each box:
- [x] I've completed this task
- [ ] This task isn't completed
-->

### Description
Replace this paragraph with a description of your changes and rationale. Provide links to an existing issue or external references/discussions, if appropriate.

### Detailed Design
Include any additional information about the design here. At minimum, show any new API:

```swift
extension Collection {
/// The new feature implemented by this pull request.
func newFeature()
}
```

### Documentation Plan
How has the new feature been documented? Have the relevant portions of the guides been updated in addition to symbol-level documentation?

### Test Plan
How is the new feature tested?

### Source Impact
What is the impact of this change on existing users? Does it deprecate or remove any existing API?

### Checklist
- [ ] I've added at least one test that validates that my change is working, if appropriate
- [ ] I've followed the code style of the rest of the project
- [ ] I've read the [Contribution Guidelines](CONTRIBUTING.md)
- [ ] I've updated the documentation if necessary
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
.DS_Store
/.build
/Packages
/*.xcodeproj
xcuserdata/
/.swiftpm
35 changes: 35 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# CHANGELOG

<!--
Add new items at the end of the relevant section under **Unreleased**.
-->

This project follows semantic versioning. While still in major version `0`,
source-stability is only guaranteed within minor versions (e.g. between
`0.0.3` and `0.0.4`). If you want to guard against potentially source-breaking
package updates, you can specify your package dependency using
`.upToNextMinor(from: "0.0.1")` as the requirement.

## [Unreleased]

*No changes yet.*

---

## [0.0.1] - 2020-10-07

- **Swift Algorithms** initial release.

---

This changelog's format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).

<!-- Link references for releases -->

[Unreleased]: https://github.com/apple/swift-algorithms/compare/0.0.1...HEAD
[0.0.1]: https://github.com/apple/swift-algorithms/releases/tag/0.0.1

<!-- Link references for pull requests -->

<!-- Link references for contributors -->

55 changes: 55 additions & 0 deletions CODE_OF_CONDUCT.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# Code of Conduct
To be a truly great community, Swift.org needs to welcome developers from all walks of life,
with different backgrounds, and with a wide range of experience. A diverse and friendly
community will have more great ideas, more unique perspectives, and produce more great
code. We will work diligently to make the Swift community welcoming to everyone.

To give clarity of what is expected of our members, Swift.org has adopted the code of conduct
defined by [contributor-covenant.org](https://www.contributor-covenant.org). This document is used across many open source
communities, and we think it articulates our values well. The full text is copied below:

### Contributor Code of Conduct v1.3
As contributors and maintainers of this project, and in the interest of fostering an open and
welcoming community, we pledge to respect all people who contribute through reporting
issues, posting feature requests, updating documentation, submitting pull requests or patches,
and other activities.

We are committed to making participation in this project a harassment-free experience for
everyone, regardless of level of experience, gender, gender identity and expression, sexual
orientation, disability, personal appearance, body size, race, ethnicity, age, religion, or
nationality.

Examples of unacceptable behavior by participants include:
- The use of sexualized language or imagery
- Personal attacks
- Trolling or insulting/derogatory comments
- Public or private harassment
- Publishing other’s private information, such as physical or electronic addresses, without explicit permission
- Other unethical or unprofessional conduct

Project maintainers have the right and responsibility to remove, edit, or reject comments,
commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of
Conduct, or to ban temporarily or permanently any contributor for other behaviors that they
deem inappropriate, threatening, offensive, or harmful.

By adopting this Code of Conduct, project maintainers commit themselves to fairly and
consistently applying these principles to every aspect of managing this project. Project
maintainers who do not follow or enforce the Code of Conduct may be permanently removed
from the project team.

This code of conduct applies both within project spaces and in public spaces when an
individual is representing the project or its community.

Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by
contacting a project maintainer at [conduct@swift.org](mailto:conduct@swift.org). All complaints will be reviewed and
investigated and will result in a response that is deemed necessary and appropriate to the
circumstances. Maintainers are obligated to maintain confidentiality with regard to the reporter
of an incident.

*This policy is adapted from the Contributor Code of Conduct [version 1.3.0](http://contributor-covenant.org/version/1/3/0/).*

### Reporting
A working group of community members is committed to promptly addressing any [reported
issues](mailto:conduct@swift.org). Working group members are volunteers appointed by the project lead, with a
preference for individuals with varied backgrounds and perspectives. Membership is expected
to change regularly, and may grow or shrink.
10 changes: 10 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
By submitting a pull request, you represent that you have the right to license
your contribution to Apple and the community, and agree by submitting the patch
that your contributions are licensed under the [Swift
license](https://swift.org/LICENSE.txt).

---

Before submitting the pull request, please make sure you have tested your
changes and that they follow the Swift project [guidelines for contributing
code](https://swift.org/contributing/#contributing-code).
49 changes: 49 additions & 0 deletions Guides/Chain.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# Chain

[[Source](https://github.com/apple/swift-algorithms/blob/main/Sources/Algorithms/Chain.swift) |
[Tests](https://github.com/apple/swift-algorithms/blob/main/Tests/AlgorithmsTests/ChainTests.swift)]

Concatenates two collections with the same element type, one after another.

This operation is available through the `chained(with:)` method on any sequence.

```swift
let numbers = [10, 20, 30].chained(with: 1...5)
// Array(numbers) == [10, 20, 30, 1, 2, 3, 4, 5]
//
let letters = "abcde".chained(with: "FGHIJ")
// String(letters) == "abcdeFGHIJ"
```

Unlike placing two collections in an array and calling `joined()`, chaining
permits different collection types, performs no allocations, and can preserve
the shared conformances of the two underlying types.

## Detailed Design

The `chained(with:)` method is added as an extension method on the `Sequence`
protocol:

```swift
extension Sequence {
public func chained<S: Sequence>(with other: S) -> Concatenation<Self, S>
where Element == S.Element
}

```

The resulting `Chain` type is a sequence, with conditional conformance to the
`Collection`, `BidirectionalCollection`, and `RandomAccessCollection` when both
the first and second arguments conform.

### Naming

This method’s and type’s name match the term of art used in other languages and
libraries.

### Comparison with other langauges

**Rust:** Rust provides a `chain` function that concatenates two iterators.

**Ruby/Python:** Ruby and Python’s `itertools` both define a `chain` function
for concatenating collections of different kinds.
91 changes: 91 additions & 0 deletions Guides/Chunked.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
# Chunked

[[Source](https://github.com/apple/swift-algorithms/blob/main/Sources/Algorithms/Chunked.swift) |
[Tests](https://github.com/apple/swift-algorithms/blob/main/Tests/AlgorithmsTests/ChunkedTests.swift)]

Break a collection into subsequences where consecutive elements pass a binary
predicate, or where all elements in each chunk project to the same value.

There are two variations of the `chunked` method: `chunked(by:)` and
`chunked(on:)`. `chunked(by:)` uses a binary predicate to test consecutive
elements, separating chunks where the predicate returns `false`. For example,
you can chunk a collection into ascending sequences using this method:

```swift
let numbers = [10, 20, 30, 10, 40, 40, 10, 20]
let chunks = numbers.chunked(by: { $0 <= $1 })
// [[10, 20, 30], [10, 40, 40], [10, 20]]
```

The `chunk(on:)` method, by contrast, takes a projection of each element and
separates chunks where the projection of two consecutive elements is not equal.

```swift
let names = ["David", "Kyle", "Karoy", "Nate"]
let chunks = names.chunked(on: \.first!)
// [["David"], ["Kyle", "Karoy"], ["Nate"]]
```

These methods are related to the [existing SE proposal][proposal] for chunking a
collection into subsequences of a particular size, potentially named something
like `chunked(length:)`. Unlike the `split` family of methods, the entire
collection is included in the chunked result — joining the resulting chunks
recreates the original collection.

```swift
c.elementsEqual(c.chunked(...).joined())
// true
```

[proposal]: https://github.com/apple/swift-evolution/pull/935

## Detailed Design

The two methods are added as extension to `Collection`, with two matching
versions that return a lazy wrapper added to `LazyCollectionProtocol`.

```swift
extension Collection {
public func chunked(
by belongInSameGroup: (Element, Element) -> Bool
) -> [SubSequence]

public func chunked<Subject: Equatable>(
on projection: (Element) -> Subject
) -> [SubSequence]
}

extension LazyCollectionProtocol {
public func chunked(
by belongInSameGroup: @escaping (Element, Element) -> Bool
) -> LazyChunked<Elements>

public func chunked<Subject: Equatable>(
on projection: @escaping (Element) -> Subject
) -> LazyChunked<Elements>
}
```

The `LazyChunked` type is bidirectional when the wrapped collection is
bidirectional.

### Complexity

The eager methods are O(_n_), the lazy methods are O(_1_).

### Naming

The operation performed by these methods is similar to other ways of breaking a collection up into subsequences. In particular, the predicate-based `split(where:)` method looks similar to `chunked(on:)`. You can draw a distinction between these different operations based on the resulting subsequences:

- `split`: *In the standard library.* Breaks a collection into subsequences, removing any elements that are considered "separators". The original collection cannot be recovered from the result of splitting.
- `chunked`: *In this package.* Breaks a collection into subsequences, preserving each element in its initial ordering. Joining the resulting subsequences re-forms the original collection.
- `sliced`: *Not included in this package or the stdlib.* Breaks a collection into potentially overlapping subsequences.


### Comparison with other langauges

**Ruby:** Ruby’s `Enumerable` class defines `chunk_while` and `chunk`, which map
to the proposed `chunked(by:)` and `chunked(on:)` methods.

**Rust:** Rust defines a variety of size-based `chunks` methods, but doesn’t
include any with the functionality described here.
Loading

0 comments on commit 6cffd04

Please sign in to comment.