rust-ndarray / ndarray

ndarray: an N-dimensional array with array views, multidimensional slicing, and efficient operations

Home Page:https://docs.rs/ndarray/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Consider alternative syntax for slicing (Index and IndexMut)?

alexpyattaev opened this issue · comments

Compared to Python, ndarray crate has an obvious difference in slicing. Arguably, this is the most annoying part of ndarray library. It would be nice to be able to do something like the following:

    let  a = SomeMatrix::default();
    let y = &a[1]);
    let x = &a[1..3]    
    let z=  &a[[1..3, 4..3]]);

Now with ndarray, this code would look quite nasty, but it does not have to. Rust does allow the Index operator (i.e., [])to be "overloaded" depending on the type of whatever is being used as "indexer", as in the example below:

#[derive(Default)]
struct ArrayBase{
    data:[u32;5]
}

impl  std::ops::Index<std::ops::Range<usize>> for ArrayBase
{        
    fn index(&self, index: std::ops::Range<usize>) ->  &Self::Output{
        &self.data[index]
    }
    type Output = [u32];
}

impl  std::ops::Index<usize> for ArrayBase
{        
    fn index(& self, index: usize) ->  &Self::Output{
        &self.data[index]
    }
    type Output = u32;
}

Using this, one could have the nice syntax actually work. Obviously, this extends to higher dimensions too:

impl <const D:usize>  std::ops::Index<[std::ops::Range<usize>;D]> for ArrayBase<D>
{        
    fn index(&self, index: [std::ops::Range<usize>;D]) ->  &Self::Output{
        todo!()
       // &self.data[index]
        
    }
    type Output = ArrayBase<D>;   
}

There are several "blindspots" here (such as inability to "collapse" dimensions when range is empty or contains only one element, or mix range and integer slicing), but the key question is whether the ndarray users find it useful/appropriate to make the necessary changes to the crate to enable this at all.