Converting cartesian index to what it would be in view

Suppose we have

a = CartesianIndices((3,3))
b = a[2:3, :] 

indx = CartesianIndex((3,3)) 
map_index_to_what_it_would_be_in_slice(?, indx::CartesianIndex) = ? 

using Test
@test a[indx] == b[map_index_to_what_it_would_be_in_slice(?, indx)] 

So, CartesianIndex((3,3)) is in b located at CartesianIndex(3,2).
I want the most efficient way to convert CartesianIndex((3,3)) to CartesianIndex((3,2)).

What I am asking for is sort of the reverse of what view does under the hood.

There are lots of ways to do this (findfirst, modular arithmetic) but I want the most performant one and preferably one that is already supported in Base. I would like this to work with arbitrary slicing of a CartesianIndices array (e.g. other_b = a[[1,3], 1]. Are there existing functions in Base to accomplish this? If not, what is the most performant approach?

Motivation: I am trying to write a higher-dimensional sparse array type that avoids using dictionaries (like SparseArrayKit does) and is faster for certain operations. Indeed, what little I have written is faster at what I need to to be faster at. But, to make my type satisfy standard array interfaces, I want to allow these arrays to be sliced (my_cartesian_sparse_array[1, :, :]) and returned as my sparse array type. Because my sparse array type stores a Vector{<:CartesianIndex} to keep track of non-sparse positions, I need to be able to map each in a subset of CartesianIndex to a new CartesianIndex corresponding with position in the sliced array.

That’s arithmetic, no?

julia> CartesianIndex((3,3)) - CartesianIndex((0,1))
CartesianIndex(3, 2)

If you have a vector of CartesianIndex, you can broadcast the arithmetic or do something lazy. I don’t think you’d be able to directly re-use Base’s view machinery to do that lazy thing, because that’s built upon the cartesian products and it works upon each dimension independently, working with the rectangular subsets.

Just in the off-chance that you aren’t aware, it sounds like you’ve implemented a COO sparse format. I think a number of folks have also implemented such things.