sets 1.2.0

Generic vectors as sets. Efficiently sorting, merging, ranking, searching, reversing, intersecting, etc.
Documentation
# Sets [<img alt="crates.io" src="https://img.shields.io/crates/v/sets?logo=rust">]https://crates.io/crates/sets [<img alt="crates.io" src="https://img.shields.io/crates/d/sets?logo=rust">]https://crates.io/crates/sets [<img alt="GitHub last commit" src="https://img.shields.io/github/last-commit/liborty/sets/HEAD?logo=github">]https://github.com/liborty/sets [![Actions Status]https://github.com/liborty/sets/workflows/test/badge.svg]https://github.com/liborty/sets/actions

Set operations, plus efficient sorting, ranking, searching, etc. The aim is to avoid moving data as much as possible. This is done by manipulating indices instead.

## Short Description

This crate defines `Struct: Set`, which wraps five kinds of sets: Empty, Unordered, Ordered, Indexed and Ranked, and methods acting upon them. These methods work on any generic vectors (or slices) of primitive end types `<T>`. Also, on any arbitrarily complex user end type, as long as the required traits `PartialOrd` and `Copy`, are implemented for it (by the user). It adds organisation and type safety to lower level methods from crate `indxvec`.

## Usage

Insert into `Cargo.toml` file, under [dependencies]: `sets = "^1"`  
The following 'use' declaration in source files makes available everything:

```rust
use sets::{Set,MutSetOps};
```

## `Set<T>`

```rust
/// The struct type for sets
#[derive(Default)]
pub struct Set<T> {
    /// type of the set
    pub stype: SType,
    /// order: ascending (true), descending (false)
    pub ascending: bool,
    /// data Vec
    pub data: Vec<T>,
    /// index Vec
    pub index: Vec<usize>
}
```

`Clone` and `Display` traits are implemented for `Set` and `SType`.  
`Default` is derived, thus `Default::default()` generates an empty set.

`SType` specifies one of the five kinds of sets. It is dealt with by 'enumeration generics'.

```rust
/// The five types of sets
#[derive(Default,Clone,Copy)]
pub enum SType {
    /// empty set
    #[default]
    Empty,
    /// unordered set
    Unordered,
    /// ordered set
    Ordered,
    /// indexed set
    Indexed,
    /// ranked set
    Ranked
}
```

### Associated Initialisers

Initialisers are associated with the struct Set, hence to invoke them, the `::` syntax is necessary, e.g. `Set::new(..)`

```rust
    /// all in one Initialiser: creates a new Set
    /// of any self_type SType, from slice d, in asc order 
    pub fn new(set_type: SType, d: &[T], asc:bool) -> Self
```

There are also explicitly named convenience functions for all STypes:
`new_empty, new_unordered, new_ordered, new_indexed, new_ranked`. All the ordered types (i.e. ordered, indexed, ranked) take a bool argument specifying ascending or descending order.

### Converters

```rust
    /// General converter - 
    /// converts s to a Set of the same type and order as self 
    /// (self only serves as a template).
    pub fn to_same(&self, s:&Self) -> Self 
```

Again, we have explicitly named converters:
`to_unordered, to_ordered, to_indexed, to_ranked`.

```rust
   let v = vec![1.,14.,2.,13.,3.,12.];
   let setv = Set::new_unordered(&v);  
   println!("{}",setv); // Display setv 
   // ordered, ascending  
   println!("{}",setv.to_ordered(true)); 
   // indexed, descending
   println!("{}",setv.to_indexed(false)); 
```

It is highly recommended to read and run [`tests/tests.rs`](https://github.com/liborty/sets/blob/main/tests/tests.rs) for more examples of usage. Use a single thread to run them. It may be a bit slower but it will write the results in the right order:

```bash
cargo test --release -- --test-threads=1 --nocapture --color always
```

The output can be seen by clicking the last badge above and then the automated test logs therein.

## Set Functions

 Some of the general methods are more efficient for the ordered and indexed sets, rather than for the unordered sets. For example, `member` and `search` will automatically use the binary search. Union is like the classical merge with duplications across the sets removed. To remove repetitions within a set, use `nonrepeat`.

The STypes of the two operands of union, intersection and difference can be different. However, they are required to have the same end-type `<T>`. This is, perhaps, a useful type discipline. 

## Trait MutSetOps

Here 'm' in the methods' names stands for 'mutable'. They overwrite the mutable set to which they are applied with the result. Thus they are not *functional* but in the context of handling large vectors, they are often simpler and more efficient. At the price of destroying the previous contents of self, of course.

```rust
/// Mutable methods for &mut Set<T>
pub trait MutSetOps<T> {
    /// Makes a Set unordered
    fn munordered(&mut self);
    /// Makes a Set ordered
    fn mordered(&mut self, quantify: &mut impl FnMut(&T) -> f64, asc:bool);
    /// Makes any Set indexed
    fn mindexed(&mut self, quantify: &mut impl FnMut(&T) -> f64, asc:bool);
    /// Converts any Set type to ranked
    fn mranked(&mut self,asc:bool);
    /// General converter: s -> Set of the same type and order as self
    fn msame(&mut self, s:&mut Self, quantify: &mut impl FnMut(&T) -> f64);
    /// Deletes the first item from self
    fn mdelete(&mut self, item:T) -> bool;
    /// Deletes all occurrences of a matching item from self, returns their count
    fn mdeleteall(&mut self, item:T) -> usize;
    /// Inserts an item of the same end-type to self
    fn minsert(&mut self, item:T);
    /// reverses the vector of explicit sets and index of indexed sets
    fn mreverse(&mut self);
    /// Deletes all repetitions
    fn mnonrepeat(&mut self); 
    /// Union of two sets of the same type
    fn munion(&mut self, s: &Self);
    /// Intersection of two sets of the same type
    fn mintersection(&mut self, s: &Self);
    /// Removing s from self (i.e. self-s)
    fn mdifference(&mut self, s: &Self);
}
```

## Release Notes (Latest First)

**Version 1.2.0** - Updated to `indxvec 1.4` and introduced compatible generalizations. No longer requiring users to globally implement `From` trait for all their types T but instead specify conversion closures on per-individual-use basis. This allows custom dynamic conversions. Beware that this breaks previous usage of `mordered` `mindexed` and `msame` methods of `MutSetOps` trait.

**Version 1.1.4** - Updated dependency `indxvec 1.4`. Added automated github actions test.

**Version 1.1.2** - Updated to indxvec 1.3.3. Pruned and simplified some code. Added `deleteall` to  trait `MutSetOps`.

**Version 1.1.1** - Eliminating unnecessary cloning. Updating to the latest dependency on  indxvec 1.2.8.

**Version 1.1.0** - Joined all four types of sets into one Struct Set. Simplified and generalised code by using enum generics.

**Version 1.0.6** - Added mutable methods `minsert` and `mdelete` to `MutSetOps`, that insert or remove one specific item to/from any of the sets. Added tests of them to `tests/tests.rs`. Updated `indxvec` dependency to its version `1.2.4` or greater.

**Version 1.0.5** - Documentation improvements.

**Version 1.0.4** - `nonrepeat` now always returns an OrderedSet. Clarified `settest`.

**Version 1.0.3** - updated to be compatible with `indxvec` version 1.2.1. Improved `munion`.

**Version 1.0.2** - some changes to printing to reflect changes to `indxvec`.

**Version 1.0.1** - some tidying up of code, no changes of functionality.

**Version 1.0.0** - stable version with some minor improvements to `README.md` (this document). Updated to `indxvec = "^1"` and Rust edition 2021.