slice-group-by

slice-group-by crate slice-group-by documentation dependency status License

An implementation of the group_by Haskell function for slice and str only.

It provides tools for efficiently iterating over a slice by groups defined by a function that specifies if two elements are in the same group.

Differences with Itertools::group_by

The [Itertools::group_by] method use a key to compare elements, this library works like, say, [slice::sort_by], it uses a comparison function. It works on every Iterator type, slice-group-by work only with mutable slice, immutable slice and immutable str, which is the power of this library, it is fast thanks to [data locality].

Also slice-group-by support multiple search algorithms (i.e. [linear], [binary] and [exponential search]) and can return groups starting from the end.

Examples

Linear Searched Immutable Groups

You will only need to define a function that returns true if two elements are in the same group.

The LinearGroupBy iterator will always gives contiguous elements to the predicate function.

```rust use slicegroupby::GroupBy;

let slice = &[1, 1, 1, 3, 3, 2, 2, 2];

let mut iter = slice.lineargroupby(|a, b| a == b);

asserteq!(iter.next(), Some(&[1, 1, 1][..])); asserteq!(iter.next(), Some(&[3, 3][..])); asserteq!(iter.next(), Some(&[2, 2, 2][..])); asserteq!(iter.next(), None); ```

Linear Searched Immutable Str Groups

You will only need to define a function that returns true if two char are in the same group.

The LinearStrGroupBy iterator will always gives contiguous char to the predicate function.

```rust use slicegroupby::StrGroupBy;

let string = "aaaabbbbb饰饰cccc";

let mut iter = string.lineargroupby(|a, b| a == b);

asserteq!(iter.next(), Some("aaaa")); asserteq!(iter.next(), Some("bbbbb")); asserteq!(iter.next(), Some("饰饰")); asserteq!(iter.next(), Some("cccc")); assert_eq!(iter.next(), None); ```

Binary Searched Mutable Groups

It is also possible to get mutable non overlapping groups of a slice.

The BinaryGroupBy/Mut and ExponentialGroupBy/Mut iterators will not necessarily gives contiguous elements to the predicate function. The predicate function should implement an order consistent with the sort order of the slice.

```rust use slicegroupby::GroupByMut;

let slice = &mut [1, 1, 1, 2, 2, 2, 3, 3];

let mut iter = slice.binarygroupby_mut(|a, b| a == b);

asserteq!(iter.next(), Some(&mut [1, 1, 1][..])); asserteq!(iter.next(), Some(&mut [2, 2, 2][..])); asserteq!(iter.next(), Some(&mut [3, 3][..])); asserteq!(iter.next(), None); ```

Exponential Searched Mutable Groups starting from the End

It is also possible to get mutable non overlapping groups of a slice even starting from end of it.

```rust use slicegroupby::GroupByMut;

let slice = &mut [1, 1, 1, 2, 2, 2, 3, 3];

let mut iter = slice.exponentialgroupby_mut(|a, b| a == b).rev();

asserteq!(iter.next(), Some(&mut [3, 3][..])); asserteq!(iter.next(), Some(&mut [2, 2, 2][..])); asserteq!(iter.next(), Some(&mut [1, 1, 1][..])); asserteq!(iter.next(), None); ```