JuliaCollections / IterTools.jl

Common functional iterator patterns
Other
152 stars 28 forks source link

Add each-function #79

Closed gustaphe closed 2 months ago

gustaphe commented 4 years ago

Add function each(ElementType, collection) that returns an iterable with eltype<:ElementType, even if collection is an element, itself iterable, with another eltype. This makes it easier to write functions with arguments ::Union{ String, Array{String} } and similar.

codecov-commenter commented 4 years ago

Codecov Report

Merging #79 into master will increase coverage by 3.26%. The diff coverage is 100.00%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master      #79      +/-   ##
==========================================
+ Coverage   73.85%   77.11%   +3.26%     
==========================================
  Files           1        1              
  Lines         283      284       +1     
==========================================
+ Hits          209      219      +10     
+ Misses         74       65       -9     
Impacted Files Coverage Δ
src/IterTools.jl 77.11% <100.00%> (+3.26%) :arrow_up:

Continue to review full report at Codecov.

Legend - Click here to learn more Δ = absolute <relative> (impact), ø = not affected, ? = missing data Powered by Codecov. Last update 21fe124...32efa26. Read the comment docs.

omus commented 4 years ago

This reminds me of:

help?> collect(::Type, ::Any)
  collect(element_type, collection)

  Return an Array with the given element type of all items in a collection or iterable. The result has the same shape and number of dimensions as collection.

  Examples
  ≡≡≡≡≡≡≡≡≡≡

  julia> collect(Float64, 1:2:5)
  3-element Array{Float64,1}:
   1.0
   3.0
   5.0

Maybe this PR should do a convert?

gustaphe commented 4 years ago

It could be done, pretty easilly, but I'm not sure I agree that it should. I imagine it would add a bit of overhead, and it won't (without bigger changes) do what you expect in some cases:

each(Tuple{Vararg{Float32,Float32}},(1.0,1.0))

will simply not recognize (1.0,1.0) as a Tuple{Float32,Float32}, and so will try to convert each Float64 to a Tuple and fail. Since these collections with iterable elements are the typical use case for these functions, I'm not sure it's a good idea to make this do convert.() except when it should be used.

gustaphe commented 4 years ago

Okay, this is actually pretty good. I don't know about the performance impact, but the code ended up being pretty clean. Is it idiomatic to use try-catch like this in Julia?

gustaphe commented 4 years ago

The failed codecov lines are ones where my editor accidentally corrected a pair of tabs to space indentation in code that isn't mine. I didn't know it would make a difference, and since it was consistent with the rest of the file I let it be. Sorry for my bad git discipline.