Struct datazoo::jagged_array::JaggedArray
source · 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>
impl<V, I: Index, E: AsRef<[I]>, VS: AsRef<[V]>> JaggedArray<V, I, E, VS>
sourcepub fn new(ends: E, data: VS) -> Result<Self, Error>
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],
],
);
sourcepub fn get(&self, direct_index: usize) -> Option<&V>
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));
sourcepub fn row(&self, index: usize) -> &[V]
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.
sourcepub fn get_row(&self, index: usize) -> Option<&[V]>
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);
sourcepub fn rows(&self, range: impl RangeBounds<usize>) -> &[V]
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.
sourcepub fn get_rows(&self, range: impl RangeBounds<usize>) -> Option<&[V]>
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(&[][..]));
sourcepub const fn rows_iter(&self) -> JaggedArrayRows<'_, V, I, E, VS> ⓘ
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>
impl<V, I: Index, E: AsRef<[I]>> JaggedArray<V, I, E>
sourcepub fn into_vecs(self) -> Vec<Vec<V>>
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>
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>
fn clone(&self) -> JaggedArray<V, I, E, VS>
1.0.0 · source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source
. Read moresource§impl<V: PartialEq, I: PartialEq + Index, E: PartialEq + AsRef<[I]>, VS: PartialEq + AsRef<[V]>> PartialEq for JaggedArray<V, I, E, VS>
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
fn eq(&self, other: &JaggedArray<V, I, E, VS>) -> bool
self
and other
values to be equal, and is used
by ==
.