Open o314 opened 1 year ago
Hi. This is a proposal for a new feature based on the declension of the well known join function with an iterable arg.
join
import Base.Iterators as _I struct _IJoin s delim end ijoin(s, delim) = _isijoinable(s) ? _IJoin(s, delim) : throw(ArgumentError("s = $s")) _isijoinable(s) = _isijoinable(Base.IteratorSize(s)) _isijoinable(::Base.HasLength) = true _isijoinable(::Base.HasShape{N}) where {N} = N==1 _isijoinable(::Base.IteratorSize) = true Base.IteratorSize(a::_IJoin) = Base.IteratorSize(a.s) Base.length(a::_IJoin) = 2*length(a.s)-1 Base.size(a::_IJoin) = let (s1,)=size(a.s); 2*s1-1 end Base.iterate(a::_IJoin) = let y=iterate(a.s); y!==nothing ? (y[1], (:yld2,y[2])) : nothing end Base.iterate(a::_IJoin, (st,sst)) = _iterate(a, Val(st), sst) _iterate(a::_IJoin, ::Val{:yld2}, sst) = let y=iterate(a.s, sst); y!==nothing ? (a.delim, (:yld3,sst)) : nothing end _iterate(a::_IJoin, ::Val{:yld3}, sst) = let y=iterate(a.s, sst); y!==nothing ? (y[1], (:yld2,y[2])) : nothing end
using Test import Base.Iterators as _I @test ijoin(["foo", "bar", "baz"], ".") |> collect == ["foo", ".", "bar", ".", "baz"] @test ijoin([1,2,3],0) |> collect == [1,0,2,0,3] @test ijoin((1,2,3),0) |> collect == [1,0,2,0,3] @test ijoin(1:5,0) |> collect == [1,0,2,0,3,0,4,0,5] @test _I.dropwhile(<(3),1:5) |> s->ijoin(s,0) |> collect == [3,0,4,0,5] @test map(ijoin(1:5, 0)) do e; 2e end == [2,0,4,0,6,0,8,0,10] @test_throws ArgumentError ijoin(fill(1,2,3),0) # this composes nicely @test map(ijoin(_I.dropwhile(<(3),1:5), 0)) do e; 2e end |> collect == [6, 0, 8, 0, 10] # more readably @test 1:5 |> s -> _I.dropwhile(<(3),s) |> # == [3, 4, 5] s -> ijoin(s, 0) |> # == [3, 0, 4, 0, 5] s -> map(s) do e; 2e end |> # == [6, 0, 8, 0, 10] collect == [6, 0, 8, 0, 10]
This will be useful to work on collections
and i dont like s -> _I.append!([first(s)], _I.flatten(zip(_I.cycle(0), _I.tail(s)))) . :)
s -> _I.append!([first(s)], _I.flatten(zip(_I.cycle(0), _I.tail(s))))
Hi. This is a proposal for a new feature based on the declension of the well known
join
function with an iterable arg.This will be useful to work on collections
and i dont like
s -> _I.append!([first(s)], _I.flatten(zip(_I.cycle(0), _I.tail(s))))
. :)