add suffix:while method #65
Conversation
There was a problem hiding this comment.
Excited to see this function added, bringing more parity between the suffix and prefix family of functions!
If changes are still being worked on, I’d recommend making use of a new feature on GitHub: Drafts. By marking this PR as a draft, it helps to convey the author’s intended state of the changes.[1]
I left a few small comments inline, but want to emphasize the primary high-level piece of feedback here, which may make several of the comments inapplicable. I think suffix(while:) should return SubSequence instead of [Element] for consistency and performance reasons.
|
|
||
| extension BidirectionalCollection { | ||
| @inlinable | ||
| public __consuming func Suffix(while predicate: (Element) throws -> Bool |
There was a problem hiding this comment.
| public __consuming func Suffix(while predicate: (Element) throws -> Bool | |
| public __consuming func suffix( | |
| while predicate: (Element) throws -> Bool |
| extension BidirectionalCollection { | ||
| @inlinable | ||
| public __consuming func Suffix(while predicate: (Element) throws -> Bool | ||
| ) rethrows -> [Element] { |
There was a problem hiding this comment.
| //===----------------------------------------------------------------------===// | ||
|
|
||
| //===----------------------------------------------------------------------===// | ||
| // Suffix(while:) |
There was a problem hiding this comment.
| // Suffix(while:) | |
| // suffix(while:) |
| extension BidirectionalCollection { | ||
| @inlinable |
There was a problem hiding this comment.
Documentation should be added. Mirroring the documentation for prefix(while:) would be a good start.
| result.reverse() | ||
| return Array(result) |
There was a problem hiding this comment.
This double-reverse operation and converting to Array shouldn’t be necessary. The last index of the collection can be retrieved with endIndex, then walked backwards using index(before:).
This would be similar to the implementation of prefix(while:)[1], but a little bit trickier. Since endIndex is beyond the subscript-able range of a collection, the index has to be moved backwards before using it to subscript the collection, and ensuring it doesn’t go before the first element (start index). In SuffixTests.swift, I made some comments about test cases that will be important for ensuring that these cases are accounted for.
| // | ||
| // This source file is part of the Swift Algorithms open source project | ||
| // | ||
| // Copyright (c) 2020 Apple Inc. and the Swift project authors |
There was a problem hiding this comment.
| // Copyright (c) 2020 Apple Inc. and the Swift project authors | |
| // Copyright (c) 2021 Apple Inc. and the Swift project authors |
| // | ||
| // This source file is part of the Swift Algorithms open source project | ||
| // | ||
| // Copyright (c) 2020 Apple Inc. and the Swift project authors |
There was a problem hiding this comment.
| // Copyright (c) 2020 Apple Inc. and the Swift project authors | |
| // Copyright (c) 2021 Apple Inc. and the Swift project authors |
| var result = ContiguousArray<Element>() | ||
| self.reverse() |
There was a problem hiding this comment.
Consistent indentation
| var result = ContiguousArray<Element>() | |
| self.reverse() | |
| var result = ContiguousArray<Element>() | |
| self.reverse() |
| var result = ContiguousArray<Element>() | ||
| self.reverse() |
There was a problem hiding this comment.
I don’t believe reverse() can be used here (won’t compile), because it is a mutating function that reverses the elements of the collection in-place. This function, suffix(while:), isn’t mutating (and should remain that way), so it can’t use self.reverse() in its implementation.
It seems that you might have meant to use the non-mutating version of that function, reversed(), which returns a reversed collection:
for element in self.reversed() {However, this comment likely won’t be applicable when changing the function to return SubSequence instead.
|
What about something like (neither compiled nor tested): extension BidirectionalCollection {
public func suffix(
while predicate: (Element) throws -> Bool
) rethrows -> SubSequence {
let start = startIndex
var result = endIndex
while result > start {
let previous = index(before: result)
guard try predicate(self[previous]) else { break }
result = previous
}
return self[result...]
}
}? |
|
@CTMacUser I think that’s pretty much exactly what I imagined the implementation would look like. Although, I think we might want to change while result > start {to while result != start {A lot of similar algorithms in the standard library use |
Co-authored-by: Xiaodi Wu <13952+xwu@users.noreply.github.com>
I agree that we should use One of the reasons stdlib uses
|
Co-authored-by: Xiaodi Wu <13952+xwu@users.noreply.github.com>
natecook1000
left a comment
There was a problem hiding this comment.
Thanks for your contribution, @michiboo! Could you update your tests to compile and pass? It looks like this is otherwise ready to go.
Co-authored-by: Xiaodi Wu <13952+xwu@users.noreply.github.com>
|
This is all set now — thanks for this implementation, @michiboo! |
Add a suffix(while:) method #62
Checklist