How to "localize" slicing an array?

How can I “localize” slicing on dimension relative to “available” indices? In the example below, I would need `L[:, j]` to mean "get all elements along dimension 1 relative to elements present in `skipzeros`". How can I do that?

``````L = rand(10, 10)
idx0 = rand(0:1, size(L))
L .= L .* idx0

skipzeros = filter(x -> x ∉ findall(L .== 0), CartesianIndices((1:10, 1:10))

for idx in skipzeros
i, j = Tuple(idx)
t1 = L[:, j] .+ 100
end
``````

Is the following what you want? (taking the liberty to simplify the code a bit)

``````L = rand(10, 10) .* rand.(Bool)

skipzeros = findall(!=(0), L)

for idx in skipzeros
same_2nd = getindex.(skipzeros, 2) .== idx[2]
t1 = L[skipzeros[same_2nd]] .+ 100
end
``````

This makes a vector `skipzeros[same_2nd]` which contains all the Cartesian indices that satisfy the condition. Then instead of slicing with `[:, j]` you can use this list of Cartesian indices to extract the corresponding values from `L`.

1 Like

This does it, thank you. Could there be a more streamlined way?

It depends what you really want to do. The given example finds the nonzero values in the same column for each nonzero value in `L`, and adds 100. So if column 3 has 5 nonzero values, it will calculate 5 times the same vector `v .+ 100` (where `v` is the list of nonzero values in column 3). A simpler way to do this is

``````L = rand(10, 10) .* rand.(Bool)
cols_nozero = filter.(!iszero, eachcol(L))
[v .+ 100 for v in cols_nozero for _ in v]
``````
1 Like