-
Notifications
You must be signed in to change notification settings - Fork 13.6k
Open
Labels
C-discussionCategory: Discussion or questions that doesn't represent real issues.Category: Discussion or questions that doesn't represent real issues.T-libsRelevant to the library team, which will review and decide on the PR/issue.Relevant to the library team, which will review and decide on the PR/issue.T-libs-apiRelevant to the library API team, which will review and decide on the PR/issue.Relevant to the library API team, which will review and decide on the PR/issue.
Description
I would expect next_back()
to include the separator before the string, i.e. the separator that separates the item from the next one. However:
"a+b+c".split_inclusive('+').collect::<Vec<_>>()
// => vec!["a+", "b+", "c"]
"a+b+c".split_inclusive('+').rev().collect::<Vec<_>>()
// => vec!["c", "b+", "a+"], but I'd expect vec!["+c", "+b", "a"]
If this behaviour is intended, it should be documented.
greenhat616 and schneiderfelipe
Metadata
Metadata
Assignees
Labels
C-discussionCategory: Discussion or questions that doesn't represent real issues.Category: Discussion or questions that doesn't represent real issues.T-libsRelevant to the library team, which will review and decide on the PR/issue.Relevant to the library team, which will review and decide on the PR/issue.T-libs-apiRelevant to the library API team, which will review and decide on the PR/issue.Relevant to the library API team, which will review and decide on the PR/issue.
Type
Projects
Milestone
Relationships
Development
Select code repository
Activity
ilyvion commentedon Aug 19, 2022
When you
rev()
an iterator, you expect to get the exact same elements as you do when you don'trev()
, but in the opposite order. I.e."a+", "b+", "c"
becomes"c", "b+", "a+"
, the reverse of the former.ilyvion commentedon Aug 19, 2022
You seem to be looking for the behavior I'd expect of an
rsplit_inclusive()
, which is not a thing. At least not yet.robertbastian commentedon Aug 19, 2022
The other split methods don't implement
DoubleEndedIterator
when the reverse search doesn't contain the same elements. From the docs:A reverse search here doesn't yield the same elements, so this should not implement
DoubleEndedIterator
.timvermeulen commentedon Aug 20, 2022
It does in your initial example. Do you have an example where it doesn't hold?
SkiFire13 commentedon Aug 20, 2022
For example
"a+++b".split_inclusive("++")
will yield["a++", "+b"]
when iterated forward, and["a+++", "b"]
when iterated backwards.Mixing calls to
next
andnext_back
is even more broken:timvermeulen commentedon Aug 20, 2022
Ah, with string patterns, yes.
split_inclusive
with a string should not have implementedDoubleEndedIterator
— it looks likeSplitInclusive
'sDoubleEndedIterator
implementation incorrectly requires that its searcher is aReverseSearcher
rather than aDoubleEndedSearcher
.split_inclusive
does seem to behave just fine forchar
separators, though.str::SplitInclusive
'sDoubleEndedIterator
impl #100806robertbastian commentedon Aug 22, 2022
No it doesn't. The iterator returns the same elements, but this is not what the action of "return the first occurence from the back including its separator from the next element" should do.
For all other
split
variants,split('a').rev()
is equivalent torsplit('a')
, but forsplit_inclusive
this is NOT the case. I think this makes theDoubleEndedIterator
a massive footgun, especially because there is norsplit_inclusive
so people will want to use.next_back()
as a workaround. This behaviour should at least be documented, I guess it cannot be removed at this point.timvermeulen commentedon Aug 22, 2022
But it does: repeated
next
calls yield"a+"
,"b+"
,"c"
, whereas repeatednext_back
calls yield"c"
,"b+"
,"a+"
. Those are the same items, in opposite order.split_inclusive(x).rev()
is not meant to behave likersplit_inclusive(x)
, it would violate theDoubleEndedIterator
contract if it did.It's also not the case for e.g.
split("aa")
, because a forward search may find different matches than a backward search. But I agree that we should probably addrsplit_inclusive
as well.robertbastian commentedon Aug 22, 2022
Yeah we're talking past each other. I'm talking about the concept of searching a string from the back, which can return different items than searching the string from the front. For
split_inclusive
this even happens when the separator is achar
. Now for all othersplit
functionsDoubleEndedIterator
implements this concept of searching a string from the back (if the pattern supports bidirectionality), but forsplit_inclusive
it's just an iterator reversal. Yes that is strictly correct because that appears to be the contract ofDoubleEndedIterator
, but thensplit_inclusive
is incomplete, it's missingrsplit_inclusive
(why wasn't this implemented together?), and it should also have a documentation section on iterator behaviour.timvermeulen commentedon Aug 22, 2022
That makes sense — whenever
split
implementsDoubleEndedIterator
, it behaves exactly likersplit
. In that sense,split_inclusive
is more likechunks
which can be reversed but (in general) doesn't behave likerchunks
.robertbastian commentedon Aug 22, 2022
So let's document? And implement
rsplit_inclusive
?timvermeulen commentedon Aug 22, 2022
It looks like
rsplit_inclusive
was part of #91546, which has been put on hold.str
split variants via a builder API rust-lang/libs-team#168Auto merge of rust-lang#100806 - timvermeulen:split_inclusive_double_…
Squashed commit of the following:
delay-timer
在 Rust v1.75 下编译失败 libnyanpasu/clash-nyanpasu#210Auto merge of #100806 - timvermeulen:split_inclusive_double_ended_bou…
Auto merge of #100806 - timvermeulen:split_inclusive_double_ended_bou…