You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Also I can't list the number of times I've done .flat_map(|x| x), so, I'm glad this was implemented.
One thing that I think should be clarified is that this only flattens one level, i.e. it will not transform [[[1, 2], [3, 4]], [[5, 6], [7, 8]]] into [1, 2, 3, 4, 5, 6, 7, 8] but [[1, 2], [3, 4], [5, 6], [7, 8]].
@leonardo-m I don't think it has to be an either-or proposition - if there are more useful additions, and there certainly are some from Itertools, they should be made irrespective of this one. Someone just has to write the PRs for those =)
Regarding .flatten() specifically, I believe it gives us easier-to-express specialization opportunities than .flat_map() does such as, flattening a vec::IntoIter<Vec<_>> with a single allocation.
Also, it was mentioned explicitly that neither of .flat_map(|x| x) nor .flat_map(identity) were rather nice and that .flatten() was clearer at rust-lang/rfcs#2306 (comment), rust-lang/rfcs#2306 (comment), and rust-lang/rfcs#2306 (review).
@clarcharr hmm, it does say in the docs that:
and you want to remove one level of indirection.
Perhaps that's not clear enough? Can we fix this during stabilization perhaps if it is not?
@Centril I mentioned that having not actually read the docs yet. ;)
I honestly think that including an example would be clearer; there are tools for languages such as JavaScript, for example, which will completely flatten an array regardless of how many levels it has. Although such a thing would be very difficult and/or impossible to do with Rust's type system, I think it'd be best for it to be clear that this is not a "deep" flatten, just a shallow one.
Not sure, how important this angle is, but just in case -- it looks like this introduces a failure for nightly builds on code that relies on itertools' version of flatten:
It would (should) do the least amount of work to return the desired result.
You want an Iterator<Item=Foo>? Easy, one operation. You want an Foo? Zero operations. You want Iterator<Item=Iterator<Item=Foo>>? Also mostly easy. Etc.
I don't see where i would use this pattern (since it prevents Foo from being an iterator over anything else, and this is a weird recursive way of doing what std::iter::repeat(...) does) but i agree that in this case a Foo can be considered as a Nested<Foo>, Nested<Iterator<Item=Foo>>, etc, but trying to .unnest() any of these constructs would result in an infinite recursion when trying to yield the first item, because of the recursive definition of Iterator for Foo
But again... What is the use case? Would in that use case it be useful to treat a Foo as a Nested<Foo>?
Activity
leonardo-m commentedon Feb 15, 2018
A flatten could be useful, but I think there are more important/useful functions/iterators to add before a flatten.
clarfonthey commentedon Feb 15, 2018
@leonardo-m Clearly not important enough for someone to write a PR/RFC before this one, though. ;)
clarfonthey commentedon Feb 15, 2018
Also I can't list the number of times I've done
.flat_map(|x| x), so, I'm glad this was implemented.One thing that I think should be clarified is that this only flattens one level, i.e. it will not transform
[[[1, 2], [3, 4]], [[5, 6], [7, 8]]]into[1, 2, 3, 4, 5, 6, 7, 8]but[[1, 2], [3, 4], [5, 6], [7, 8]].Centril commentedon Feb 15, 2018
@leonardo-m I don't think it has to be an either-or proposition - if there are more useful additions, and there certainly are some from Itertools, they should be made irrespective of this one. Someone just has to write the PRs for those =)
Regarding
.flatten()specifically, I believe it gives us easier-to-express specialization opportunities than.flat_map()does such as, flattening avec::IntoIter<Vec<_>>with a single allocation.Also, it was mentioned explicitly that neither of
.flat_map(|x| x)nor.flat_map(identity)were rather nice and that.flatten()was clearer at rust-lang/rfcs#2306 (comment), rust-lang/rfcs#2306 (comment), and rust-lang/rfcs#2306 (review).@clarcharr hmm, it does say in the docs that:
Perhaps that's not clear enough? Can we fix this during stabilization perhaps if it is not?
clarfonthey commentedon Feb 15, 2018
@Centril I mentioned that having not actually read the docs yet. ;)
I honestly think that including an example would be clearer; there are tools for languages such as JavaScript, for example, which will completely flatten an array regardless of how many levels it has. Although such a thing would be very difficult and/or impossible to do with Rust's type system, I think it'd be best for it to be clear that this is not a "deep" flatten, just a shallow one.
Centril commentedon Feb 15, 2018
@clarcharr Updated the docs with your example.
clarfonthey commentedon Feb 16, 2018
Awesome! Thanks
yrashk commentedon Feb 26, 2018
Not sure, how important this angle is, but just in case -- it looks like this introduces a failure for nightly builds on code that relies on itertools' version of flatten:
https://it.sit-it.org/issue/fe5e68e5-22a1-4bc3-8ebf-36586460ba27
https://travis-ci.org/sit-it/sit/jobs/346132639#L1129
It's a trivial fix for the code that uses it (the patch is in the first link) but I thought it is worth mentioning this aspect.
24 remaining items
reuvenpo commentedon Jun 18, 2018
I'm not sure i understand.
Do you mean iterators of a type that always yield iterators of the same type?
(Is that even a useful pattern?)
SoniEx2 commentedon Jun 18, 2018
It would (should) do the least amount of work to return the desired result.
You want an Iterator<Item=Foo>? Easy, one operation. You want an Foo? Zero operations. You want Iterator<Item=Iterator<Item=Foo>>? Also mostly easy. Etc.
reuvenpo commentedon Jun 18, 2018
I don't see where i would use this pattern (since it prevents Foo from being an iterator over anything else, and this is a weird recursive way of doing what
std::iter::repeat(...)does) but i agree that in this case aFoocan be considered as aNested<Foo>,Nested<Iterator<Item=Foo>>, etc, but trying to.unnest()any of these constructs would result in an infinite recursion when trying to yield the first item, because of the recursive definition ofIterator for FooBut again... What is the use case? Would in that use case it be useful to treat a
Fooas aNested<Foo>?Centril commentedon Jun 18, 2018
Can we move discussion on flattening nested stuff to internals.rust-lang.org?
reuvenpo commentedon Jun 18, 2018
(I'll have to open an account, but)
Sure
Rollup merge of rust-lang#51511 - Centril:feature/stabilize_iterator_…
Rollup merge of rust-lang#51511 - Centril:feature/stabilize_iterator_…
Auto merge of #51965 - pietroalbini:rollup, r=pietroalbini
Rollup merge of rust-lang#51511 - Centril:feature/stabilize_iterator_…
Auto merge of #51969 - pietroalbini:rollup, r=pietroalbini
Cajun75 commentedon Nov 14, 2024
Cajun75 commentedon Nov 14, 2024