I’m trying to get more familiar with using Transducers.jl or related functions that avoid loops - just to learn. Let’s say I have this simple vector x = Bool[1,1,0,0,1,1,0,1]
and I want to find the indices of adjacent True, so in this case, get:
(1,2)
(5,6)
(8,8)
I came this far: collect(Enumerate(), x) |> Filter(x->x[2]==1) |> Map(x -> x[1]) |> collect
Which gives:
5-element Vector{Int64}:
1
2
5
6
8
Then I should basically “loop” through these to get the adjacent values I thought of fold but that needs the same output format as the input. Would be curious to see how this can be solved without writing a loop
EDIT
Maybe findall would be easier to get the indexes haha: findall(x->x==true, z)
5-element Vector{Int64}:
1
2
5
6
8
But the latter step I’m not sure how to solve without a loop
I want to get the indices of the 1s or interval when multiple adjacent 1s are present. Hence all intervals for ones would be [ [1,2], [5,6], [8,8] ] the last one is not really an “interval” but there is no adjacent value.
Found a way using Tranducers.jl, not entirely sure if this elegant collect(Enumerate(), x) |> PartitionBy(x -> x[2] == true) |> Filter(x -> x[1][2] == true) |> Map(x-> (x[argmin(x)][1], x[argmax(x)][1])) |> collect
Not that bad with 49 allocs, but I guess pretty bad for readability lol
Sorry if my joke wasn’t clear – the history of programming has been hiding GOTOs with loops and if-else because it adds clarity and brevity to the code. Functional programming hides loops and if-else to add further clarity and brevity.