JuliaCollections / IterTools.jl

Common functional iterator patterns
Other
154 stars 29 forks source link

Would takewhile be a natural candidate for IterTools.jl? #51

Closed reinermartin closed 5 years ago

reinermartin commented 5 years ago

Would a takewhile function be a natural function to add to IterTools? It consumes a given iterator as long as a given condition is met.

So collect(TakeWhile(Base.Iterators.countfrom(1), x-> x^2 <= 50)) would yield [1, 2, 3, 4, 5, 6].

My own (simplistic?) implementation looks like this:

struct TakeWhile{I}
    xs::I
    cond::Function
end

Base.iterate(it::TakeWhile) = iterate(it.xs)

function Base.iterate(it::TakeWhile, state)
    (val, state) = iterate(it.xs, state)
    it.cond(state) || return nothing
    val, state
end

Base.IteratorSize(it::TakeWhile) = Base.SizeUnknown()
iamed2 commented 5 years ago

Yes, although it could also be takeuntil

reinermartin commented 5 years ago

Sure; I was thinking of the Python module itertools, which provides takewhile(). Best is to have both, as this is such a basic functional programming concept.

iamed2 commented 5 years ago

Ah well we can choose the Python-similar one then :)

ararslan commented 5 years ago

FWIW takewhile is actually the standard name for this, and is provided in Scheme, C#, Haskell, Java, Kotlin, ...

ararslan commented 5 years ago

Your implementation looks good, I'd just swap the argument order to the constructor so that the function comes first, which is conventional.

reinermartin commented 5 years ago

In the meantime, I have prepared code for takewhile with tests and doc, but I can not 'publish branch' or create a 'pull request'. I get

"Authentication failed. You may not have permission to access the repository or the repository may have been archived. Open options and verify that you're signed in with an account that has permission to access this repository"

if I try to publish from GitHub Desktop. Are there any special rights I need to do this?

Sorry, this is a total beginner's question - I have never contributed to any open source before.

ararslan commented 5 years ago

You can fork the package to your account by clicking "Fork" in the upper right corner of the page, next to "Star" and "Watch." You can then add add your fork as a Git remote, push your changes to your fork, then open a PR based on that.

reinermartin commented 5 years ago

Thanks ararslan, I'll try that now.

reinermartin commented 5 years ago

OK, I created a fork, added my code to three files manually, and created a pull request - first time for me!

reinermartin commented 5 years ago

Oh, "All checks have failed" - would have been too easy... :-(

reinermartin commented 5 years ago

So I fixed (one) bug (copied one 'end' too many) - do I have to create new pull request, or what do I need to do?

ararslan commented 5 years ago

You can commit the changes to your branch then push to the remote again, which will automatically update the existing pull request.

reinermartin commented 5 years ago

If this works out I'll add 'takeuntil' some other day

iamed2 commented 5 years ago

If this works out I'll add 'takeuntil' some other day

Don't worry about it :)

iamed2 commented 5 years ago

Added in https://github.com/JuliaCollections/IterTools.jl/pull/54

ararslan commented 5 years ago

I have never contributed to any open source before.

Your first contribution was a great one!