pub struct JaggedArray<V, I: Index = u32, E: AsRef<[I]> = Box<[I]>, VS: AsRef<[V]> = Box<[V]>> { /* private fields */ }
Expand description

A matrix of variable length row.

Limitation

  • A JaggedArray has at least one row, even if it is an empty row.
  • This is a read-only data structure, Once a JaggedArray is built, it’s impossible to mutate it.

Consider using JaggedVec if you want to push and pop rows from the jagged array.

Design

Instead of storing a Vec<Vec<V>>, JaggedArray<V> stores (1) an array of indices of slice ends (2) a single Vec<V>.

The API abstracts this design and pretends fairly successfully that we have an array of arrays underneath.

Genericity

JaggedArray is generic over the index type. By default, it is Box<[u32]>, but you can swap it to anything you like depending on your use case.

For example, you can store a fixed-height array for the same stack space as the default Box<[u32]> as follow:

use datazoo::JaggedArray;

let my_strs = vec!["one", "five", "ten", "eleven!", "fifth", "potato", "42", "twenth"];
// This has 9 rows, and all but the last row have a maximum size of 2¹⁶
let compact_array = JaggedArray::<&str, u16, [u16; 8]>::new([0; 8], my_strs.into());

Implementations§

source§

impl<V, I: Index, E: AsRef<[I]>, VS: AsRef<[V]>> JaggedArray<V, I, E, VS>

source

pub fn len(&self) -> usize

How many cells are contained in this JaggedArray.

source

pub fn is_empty(&self) -> bool

Is this array empty (no cells, it has at least one empty row).

source

pub fn height(&self) -> usize

How many rows this JaggedArray has.

source

pub fn new(ends: E, data: VS) -> Result<Self, Error>

Create a JaggedArray of + 1 rows, values of ends are the end indicies (exclusive) of each row in data.

Consider using jagged_array::Builder instead of new for a less error-prone version, in case E = Box<[I]>.

Note that the 0 index and the last index should be elided. The last row will be the values between the last end in ends and the total size of the data array.

Errors
  • An ends[i] > data.len()
  • An ends[i+1] < ends[i]
Example
use datazoo::JaggedArray;

let ends = [0_u32, 0, 3, 4, 7, 9, 10, 10];
let data = vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 32];
let jagged = JaggedArray::new(ends, data.into()).unwrap();
let iliffe = jagged.into_vecs();

assert_eq!(iliffe.len(), ends.len() + 1);
assert_eq!(
    iliffe,
    vec![
        vec![],
        vec![],
        vec![0, 1, 2],
        vec![3],
        vec![4, 5, 6],
        vec![7, 8],
        vec![9],
        vec![],
        vec![11, 32],
    ],
);
source

pub fn get(&self, direct_index: usize) -> Option<&V>

Get V at exact direct_index ignoring row sizes, acts as if the whole array was a single row.

None when direct_index is out of bound.

Example
use datazoo::JaggedArray;

let ends = &[0_u32, 0, 3, 4, 7, 9, 10, 10];
let data = vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9].into_boxed_slice();
let jagged = JaggedArray::new(ends, data).unwrap();

assert_eq!(jagged.get(4), Some(&4));
source

pub fn row(&self, index: usize) -> &[V]

Get slice to row at given index.

Panics

See JaggedArray::get_row for an example and a non-panicking version.

source

pub fn get_row(&self, index: usize) -> Option<&[V]>

Get row slice at given index.

Returns None if index is out of bound (index >= self.height()).

Example
let array = datazoo::jagged_array::Builder::<i64>::new()
    .add_row([1, 2, 3]).add_row([4, 5, 6]).add_row([]).add_row([7, 8, 9])
    .build();

assert_eq!(array.get_row(1), Some(&[4, 5, 6][..]));
assert_eq!(array.get_row(4), None);
source

pub fn rows(&self, range: impl RangeBounds<usize>) -> &[V]

Same as JaggedArray::row, but for a range of rows instead of individual rows.

See more details at JaggedArray::get_rows.

Panics

If the range is out of bounds.

source

pub fn get_rows(&self, range: impl RangeBounds<usize>) -> Option<&[V]>

Same as JaggedArray::get_row, but for a range of rows instead of individual rows.

Returns None if the range is out of bound.

Example
let array = datazoo::jagged_array::Builder::<i64>::new()
    .add_row([1, 2, 3]).add_row([4, 5, 6]).add_row([]).add_row([7, 8, 9])
    .build();

assert_eq!(array.get_rows(..), Some(&[1, 2, 3, 4, 5, 6, 7, 8, 9][..]));
assert_eq!(array.get_rows(2..), Some(&[7, 8, 9][..]));
assert_eq!(array.get_rows(2..3), Some(&[][..]));
source

pub const fn rows_iter(&self) -> JaggedArrayRows<'_, V, I, E, VS>

Iterate over every individual row slices of this JaggedArray.

source§

impl<V, I: Index, E: AsRef<[I]>> JaggedArray<V, I, E>

source

pub fn into_vecs(self) -> Vec<Vec<V>>

Turn this compact jagged array into a sparse representation.

The returned Vec<Vec<V>> is an Iliffe vector. Iterating over it will be much slower than iterating over JaggedArray, but extending individual rows is much less costly.

Trait Implementations§

source§

impl<V: Clone, I: Clone + Index, E: Clone + AsRef<[I]>, VS: Clone + AsRef<[V]>> Clone for JaggedArray<V, I, E, VS>

source§

fn clone(&self) -> JaggedArray<V, I, E, VS>

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl<V: Debug, I: Index, E: AsRef<[I]>> Debug for JaggedArray<V, I, E>

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl<V: PartialEq, I: PartialEq + Index, E: PartialEq + AsRef<[I]>, VS: PartialEq + AsRef<[V]>> PartialEq for JaggedArray<V, I, E, VS>

source§

fn eq(&self, other: &JaggedArray<V, I, E, VS>) -> bool

This method tests for self and other values to be equal, and is used by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
source§

impl<V: Eq, I: Eq + Index, E: Eq + AsRef<[I]>, VS: Eq + AsRef<[V]>> Eq for JaggedArray<V, I, E, VS>

source§

impl<V, I: Index, E: AsRef<[I]>, VS: AsRef<[V]>> StructuralEq for JaggedArray<V, I, E, VS>

source§

impl<V, I: Index, E: AsRef<[I]>, VS: AsRef<[V]>> StructuralPartialEq for JaggedArray<V, I, E, VS>

Auto Trait Implementations§

§

impl<V, I, E, VS> RefUnwindSafe for JaggedArray<V, I, E, VS>where E: RefUnwindSafe, VS: RefUnwindSafe,

§

impl<V, I, E, VS> Send for JaggedArray<V, I, E, VS>where E: Send, VS: Send,

§

impl<V, I, E, VS> Sync for JaggedArray<V, I, E, VS>where E: Sync, VS: Sync,

§

impl<V, I, E, VS> Unpin for JaggedArray<V, I, E, VS>where E: Unpin, VS: Unpin,

§

impl<V, I, E, VS> UnwindSafe for JaggedArray<V, I, E, VS>where E: UnwindSafe, VS: UnwindSafe,

Blanket Implementations§

source§

impl<T> Any for Twhere T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

source§

impl<T, U> Into<U> for Twhere U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

source§

impl<T> ToOwned for Twhere T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for Twhere U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.