Struct mset::MultiSet

source ·
pub struct MultiSet<T, S = RandomState> { /* private fields */ }
Expand description

A hash multiset implemented as a HashMap where the value is usize.

As with the HashMap type, a MultiSet requires that the elements implement the Eq and Hash traits. This can frequently be achieved by using #[derive(PartialEq, Eq, Hash)]. If you implement these yourself, it is important that the following property holds:

e1 == e2 -> hash(e1) == hash(e2)

In other words, if two elements are equal, their hashes must also be equal.

It is a logic error for an item to be modified in such a way that the item’s hash, as determined by the Hash trait, or its equality, as determined by the Eq trait, changes while it is in the multiset. This is normally only possible through Cell, RefCell, global state, I/O, or unsafe code.

In addition to these constraints, elements must implement the Clone trait. As above, this can frequently be derived using #[derive(Clone)] or adding the Clone trait to the other traits in an existing #derive[...] macro. A multiset stores the first element inserted with and a usize. When an api call returns one or more elements it will return clones of that initial element. For complex elements this can sometimes lead to unexpected behavior, and in those cases it may be preferable to explore other hash functions or non-hash map backed multiset implementations.

Examples

use mset::MultiSet;

// Ocassionally, type inference will let us omit an explicit type signature
// (which would be `MultiSet<String>` in this example).
let mut bag = MultiSet::new();

// Add some words
bag.insert("contemplate");
bag.insert("the");
bag.insert("variations");
bag.insert("of");
bag.insert("the");
bag.insert("23");
bag.insert("letters");

// Check for a specific one.
if !bag.contains(&"Hacedor") {
    println!("We have {} words, but Hacedor ain't one.",
             bag.distinct_elements().len());
}

// Remove a word
bag.remove(&"23");

// Iterate over everything.
for (word, count) in &bag {
    println!("{}: {}", word, count);
}

The easiest way to use MultiSet with a custom type is to derive Eq, Hash, and Clone. We must also derive PartialEq, this will in the future be implied by Eq.

use mset::MultiSet;
#[derive(Hash, Eq, PartialEq, Debug, Clone)]
struct GuineaPig {
    name: String,
    weight: usize,
}

let mut gps = MultiSet::new();

gps.insert(GuineaPig { name: String::from("Mumpkans"), weight: 8 });
gps.insert(GuineaPig { name: String::from("Mumpkans"), weight: 8 });
gps.insert(GuineaPig { name: String::from("Mr. Mister"), weight: 5 });
gps.insert(GuineaPig { name: String::from("Popchop"), weight: 12 });
gps.insert(GuineaPig { name: String::from("Fuzzable"), weight: 9 });

// Use derived implementation to print the guinea pigs.
for x in &gps {
    println!("{:?}", x);
}

A MultiSet with fixed list of elements can be initialized from an array:

use mset::MultiSet;

let gps: MultiSet<&'static str> =
    ["Deathmlom", "Bun Roy", "Funbees", "Sporky", "Bun Roy"].iter().copied().collect();
// use the values stored in the multiset

Implementations§

Create an empty MultiSet.

The multiset is initially created with a capacity of 0 distinct elements, so it will not allocate until it is first inserted into.

Examples
use mset::MultiSet;

let mset: MultiSet<char> = MultiSet::new();
assert_eq!(mset.len(), 0);
assert_eq!(mset.distinct_elements().len(), 0);

Create an empty MultiSet with the specified capacity.

The multiset will be able to hold at least capacity distinct elements without reallocating. If capacity is 0, the multiset will not allocate on creation.

Examples
use mset::MultiSet;
let mset: MultiSet<i32> = MultiSet::with_capacity(10);
assert!(mset.capacity() >= 10);

Returns the number of distinct elements the multiset can hold without reallocating.

Examples
use mset::MultiSet;

let mset: MultiSet<i32> = MultiSet::with_capacity(100);
assert!(mset.capacity() >= 100);

An iterator visiting all distinct elements and counts in arbitrary order. The iterator element type is (&T, &usize).

Examples
use mset::MultiSet;
let mut mset = MultiSet::new();
mset.insert("a");
mset.insert("b");

// Will print in an arbitrary order.
for (elem, count) in mset.element_counts() {
    println!("{}: {}", elem, count);
}

An iterator visiting all distinct elements in arbitrary order. The iterator element type is &'a T.

Examples
use mset::MultiSet;

let mut mset: MultiSet<_> = MultiSet::new();
mset.insert('a');
mset.insert('a');
mset.insert('b');
mset.insert('c');

// Will print in an arbitrary order.
for e in mset.distinct_elements() {
    println!("{}", e);
}

Returns the total number of elements in the multiset.

This is dynamically computed and runs in O(N) time.

Examples
use mset::MultiSet;

let mut mset: MultiSet<_> = MultiSet::new();
assert_eq!(mset.len(), 0);

mset.insert_times('a', 10);
mset.insert('b');
mset.insert('b');

assert_eq!(mset.len(), 12);

Returns true if the multiset contains no elements.

Examples
use mset::MultiSet;

let mut mset: MultiSet<_> = MultiSet::new();
assert!(mset.is_empty());

mset.insert('L');

assert!(!mset.is_empty());

Clears the multiset, removing all values.

Examples
use mset::MultiSet;

let mut mset: MultiSet<_> = MultiSet::new();

mset.insert('v');

assert_eq!(mset.is_empty(), false);

mset.clear();

assert!(mset.is_empty());

Create an empty MultiSet using the specified hasher.

The created MutliSet has the default initial capacity.

Examples
use mset::MultiSet;
use std::collections::hash_map::RandomState;

let s = RandomState::new();
let mut mset = MultiSet::with_hasher(s);
mset.insert_times(1, 2);

Create an empty MultiSet with the specified capacity, using hash_builder to hash the elements.

The created MutliSet will hold at least capacity elements without reallocating. If capacity is 0, the MultiSet will not allocate.

Examples
use mset::MultiSet;
use std::collections::hash_map::RandomState;

let s = RandomState::new();
let mut mset = MultiSet::with_capacity_and_hasher(10, s);
mset.insert_times(1, 2);

Returns a reference to the map’s BuildHasher.

Examples
use mset::MultiSet;
use std::collections::hash_map::RandomState;

let hasher = RandomState::new();
let mset: MultiSet<char> = MultiSet::with_hasher(hasher);
let hasher: &RandomState = mset.hasher();

Reserves capacity for at least additional more distinct elements to be inserted in the HashMap. The collection may reserve more space to avoid frequent reallocations.

Panics

Panics if the new allocation size overflows usize.

Examples
use mset::MultiSet;

let mut mset: MultiSet<usize> = MultiSet::new();
mset.reserve(10);

Shrinks the capacity of the multiset as much as possible. It will drop down while maintaining the internal rules and possibly leaving some space in accordance with the resize policy.

Examples
use mset::MultiSet;

let mut mset: MultiSet<_> = MultiSet::with_capacity(100);
mset.insert(1);
mset.insert(2);

assert!(mset.capacity() >= 100);

mset.shrink_to_fit();

assert!(mset.capacity() >= 2);

An iterator visiting all distinct elements and counts in arbitrary order. The iterator element type is &'a (T, usize).

Examples
use mset::MultiSet;
let mut mset = MultiSet::new();
mset.insert("a");
mset.insert("b");

// Will print in an arbitrary order.
for (elem, count) in mset.iter() {
    println!("{}: {}", elem, count);
}

An iterator visiting all elements in arbtitrary order. The iterator element type is T

Examples
use mset::MultiSet;
let mut mset = MultiSet::new();
mset.insert("a");
mset.insert("a");
mset.insert("b");

for elem in mset.iter_with_multiplicity() {
    println!("{}", elem);
}

Returns true if self has no elements in common with other. This is equivalent to checking for an empty intersection.

Examples
use mset::MultiSet;

let p: MultiSet<_> = [1, 2, 2, 3].iter().cloned().collect();
let mut q = MultiSet::new();

assert!(p.is_disjoint(&q));
q.insert(0);
assert!(p.is_disjoint(&q));
q.insert(4);
assert!(p.is_disjoint(&q));
q.insert(3);
assert_eq!(p.is_disjoint(&q), false);

Returns true if the multiset is a subset of another, i.e., other contains at least all the values in self.

Examples
use mset::MultiSet;

let msup: MultiSet<_> = [1, 2, 2, 3].iter().cloned().collect();
let mut mset = MultiSet::new();

assert!(mset.is_subset(&msup));
mset.insert(2);
assert!(mset.is_subset(&msup));
mset.insert(2);
assert!(mset.is_subset(&msup));
mset.insert(2);
assert_eq!(mset.is_subset(&msup), false);

Returns true if the multiset is a superset of another, i.e., self contains at least all the values in other.

Examples
use mset::MultiSet;

let msub: MultiSet<_> = [1, 2, 2].iter().copied().collect();
let mut mset = MultiSet::new();

assert_eq!(mset.is_superset(&msub), false);

mset.insert(0);
mset.insert(1);
assert_eq!(mset.is_superset(&msub), false);

mset.insert(2);
assert_eq!(mset.is_superset(&msub), false);

mset.insert(2);
assert_eq!(mset.is_superset(&msub), true);

Add a value to the multiset.

If the multiset did not have this value present, true is returned.

If the multiset did have this value present, false is returned.

Examples
use mset::MultiSet;

let mut mset: MultiSet<_> = MultiSet::new();
assert_eq!(mset.insert('a'), true);
assert_eq!(mset.insert('a'), false);

assert_eq!(mset.len(), 2);
assert_eq!(mset.distinct_elements().len(), 1);

Add a value to the multiset some number of times

If the multiset did not have this value present, true is returned.

If the multiset did have this value present, false is returned.

Examples
use mset::MultiSet;

let mut mset: MultiSet<_> = MultiSet::new();
assert!(mset.insert_times('a', 10));
assert!(!mset.insert_times('a', 2));

assert_eq!(mset.distinct_elements().len(), 1);
assert_eq!(mset.len(), 12);
assert_eq!(mset.get(&'a'), Some(12));

Remove a value from the multiset. Returns whether the value was present in the multiset.

use mset::MultiSet;

let mut mset: MultiSet<_> = MultiSet::new();
assert_eq!(mset.len(), 0);
mset.insert('a');

mset.shrink_to_fit();
assert_eq!(mset.len(), 1);
assert_eq!(mset.remove(&'a'), true);
assert_eq!(mset.remove(&'a'), false);

mset.shrink_to_fit();

assert_eq!(mset.capacity(), 0);

Remove multiple values from the multiset. Returns whether the values were present in the multiset.

use mset::MultiSet;

let mut mset: MultiSet<_> = MultiSet::new();
mset.insert_times('c', 10);

assert_eq!(mset.remove_times(&'c', 2), true);
assert_eq!(mset.remove_times(&'c', 10), false);
assert_eq!(mset.len(), 0);

assert!(mset.is_empty());

Removes all instances of an element from the multiset and returns the multiplicity, if the element is in the multiset.

Examples
use mset::MultiSet;

let mut mset: MultiSet<_> = vec!['a', 'b', 'c', 'b', 'a'].iter().cloned().collect();
assert_eq!(mset.take(&'b'), Some(('b', 2)));
assert_eq!(mset.take(&'d'), None);

Retains only the elements specified by the predicate.

In other words, remove all pairs (elem, multiplicty) such that f(&k, usize) returns false.

Examples
use mset::MultiSet;

let mut mset: MultiSet<_> = vec!['a', 'b', 'c', 'b', 'a'].iter().cloned().collect();
mset.retain(|_, m: usize| m % 2 == 0);

assert_eq!(mset.distinct_elements().len(), 2);
assert_eq!(mset.len(), 4);

Clears the multiset, returning all elements in an iterator.

Examples
use mset::MultiSet;

let mut mset: MultiSet<_> = MultiSet::new();
for u in &[1i32, 2i32, 3i32, 3i32, 2i32, 1i32] {
    mset.insert(*u);
}

for (e, m) in mset.drain() {
    assert!(e == 1 || e == 2 || e == 3);
    assert_eq!(m, 2);
}

Visits the values representing the difference, i.e., the values that are in self but no in other.

Examples
use mset::MultiSet;
let p: MultiSet<_> = ['a', 'b', 'c', 'd'].iter().cloned().collect();
let q: MultiSet<_> = ['d', 'b', 'c', 'd'].iter().cloned().collect();

for e in p.difference(&q) {
    println!("{}", e);
}

// can be thought of as `p - q`
let diff: MultiSet<_> = p.difference(&q).collect();
assert_eq!(diff, ['a'].iter().collect());

// note that difference is not symetric,
// and `q - p` has a different result:
let diff: MultiSet<_> = q.difference(&p).collect();
assert_eq!(diff, ['d'].iter().collect());

Visits the values representing the symmetric difference, i.e., the values that are in self or in other but not in both.

Examples
use mset::MultiSet;
let p: MultiSet<_> = ['a', 'b', 'c', 'd'].iter().cloned().collect();
let q: MultiSet<_> = ['d', 'b', 'c', 'd'].iter().cloned().collect();

for e in p.symmetric_difference(&q) {
    println!("{}", e);
}

let diff1: MultiSet<_> = p.symmetric_difference(&q).collect();
let diff2: MultiSet<_> = q.symmetric_difference(&p).collect();
assert_eq!(diff1, diff2);
assert_eq!(diff1, ['a', 'd'].iter().collect());

Visits the values representing the intersection, i.e., the values that are both in self and other.

Examples
use mset::MultiSet;
let p: MultiSet<_> = ['a', 'b', 'c', 'd'].iter().cloned().collect();
let q: MultiSet<_> = ['d', 'b', 'c', 'd'].iter().cloned().collect();

for e in p.intersection(&q) {
    println!("{}", e);
}

let diff1: MultiSet<_> = p.symmetric_difference(&q).collect();
let diff2: MultiSet<_> = q.symmetric_difference(&p).collect();
assert_eq!(diff1, diff2);
assert_eq!(diff1, ['a', 'd'].iter().collect());

Visits the values representing the union, i.e., all the values in self or other.

Examples
use mset::MultiSet;
let p: MultiSet<_> = ['a', 'b', 'c', 'd'].iter().cloned().collect();
let q: MultiSet<_> = ['b', 'c', 'd'].iter().cloned().collect();

// Print 'a', 'b', 'b', 'c', 'c', 'd', 'd', 'd' in an arbitrary order.
for e in p.union(&q) {
    println!("{}", e);
}

let union: MultiSet<_> = p.union(&q).collect();
assert_eq!(union, ['a', 'b', 'b', 'c', 'c', 'd', 'd'].iter().collect());

Returns true if the multiset contains a value.

Examples
use mset::MultiSet;

let mut mset: MultiSet<_> = MultiSet::new();
mset.insert_times(1, 10);
mset.insert_times(2, 2);

assert_eq!(mset.contains(&1), true);
assert_eq!(mset.contains(&5), false);

Returns a usize representing how many of the provided element are stored in the mset.

Multiplicty is represented as a usize but 0 is an invalid value and Size(0) is an invalid return value. Expect None instead.

Examples
use mset::MultiSet;

let mut mset: MultiSet<_> = MultiSet::new();
mset.insert('a');

assert_eq!(mset.get(&'a'), Some(1));
assert_eq!(mset.get(&'b'), None);

Returns the element-multiplicity pair corresponding to the supplied element.

Examples
use mset::MultiSet;

let mut mset: MultiSet<_> = MultiSet::new();
mset.insert('a');

assert_eq!(mset.get_element_multiplicity(&'a'), Some((&'a', &1)));
assert_eq!(mset.get_element_multiplicity(&'b'), None);

Trait Implementations§

Returns the intersection of self and rhs (right hand side) as a new MultiSet<T, S>.

Examples
use mset::MultiSet;

let p: MultiSet<_> = vec![1, 2, 3, 3, 3].into_iter().collect();
let q: MultiSet<_> = vec![2, 3, 4, 5].into_iter().collect();

let mset = &p & &q;

let mut i = 0;
let expected = [2, 3];
for (e, m) in &mset {
    assert!(expected.contains(e));
    println!("{} {}", e, m);
    i += (e * m);
}

assert_eq!(i, expected.iter().sum());
The resulting type after applying the & operator.

Returns the union of self and rhs (right hand side) as a new MultiSet<T, S>.

Examples
use mset::MultiSet;

let p: MultiSet<_> = vec![1, 2, 3, 3].into_iter().collect();
let q: MultiSet<_> = vec![3, 3, 4, 5].into_iter().collect();

let mset = &p | &q;

let mut i = 0;
let expected = [1, 2, 3, 3, 3, 3, 4, 5];
for (e, m) in &mset {
    assert!(expected.contains(e));
    i += (e * m);
}

assert_eq!(i, expected.iter().sum());
The resulting type after applying the | operator.

Returns the symmetric difference of self and rhs (right hand side) as a new MultiSet<T, S>.

Examples
use mset::MultiSet;

let p: MultiSet<_> = vec![1, 2, 3, 3].into_iter().collect();
let q: MultiSet<_> = vec![3, 4, 5].into_iter().collect();

let mset = &p ^ &q;

let mut i = 0;
let expected = [1, 2, 3, 4, 5];
for (e, m) in &mset {
    assert!(expected.contains(e));
    i += (e * m);
}

assert_eq!(i, expected.iter().sum());
The resulting type after applying the ^ operator.
Returns a copy of the value. Read more
Performs copy-assignment from source. Read more
Formats the value using the given formatter. Read more

Creates a new, empty MultiSet.

Extends a collection with the contents of an iterator. Read more
🔬This is a nightly-only experimental API. (extend_one)
Extends a collection with exactly one element.
🔬This is a nightly-only experimental API. (extend_one)
Reserves capacity in a collection for the given number of additional elements. Read more
Extends a collection with the contents of an iterator. Read more
🔬This is a nightly-only experimental API. (extend_one)
Extends a collection with exactly one element.
🔬This is a nightly-only experimental API. (extend_one)
Reserves capacity in a collection for the given number of additional elements. Read more
Extends a collection with the contents of an iterator. Read more
🔬This is a nightly-only experimental API. (extend_one)
Extends a collection with exactly one element.
🔬This is a nightly-only experimental API. (extend_one)
Reserves capacity in a collection for the given number of additional elements. Read more
Extends a collection with the contents of an iterator. Read more
🔬This is a nightly-only experimental API. (extend_one)
Extends a collection with exactly one element.
🔬This is a nightly-only experimental API. (extend_one)
Reserves capacity in a collection for the given number of additional elements. Read more

Create a MultiSet from a HashMap<T, usize>.

Examples

use mset::MultiSet;
use std::collections::HashMap;

let mut m = HashMap::new();
m.insert('a', 4);
m.insert('z', 1);

let mset: MultiSet<_> = MultiSet::from(m);

assert_eq!(mset.distinct_elements().len(), 2);
assert_eq!(mset.len(), 5);
Converts to this type from the input type.
Creates a value from an iterator. Read more
Creates a value from an iterator. Read more
The type of the elements being iterated over.
Which kind of iterator are we turning this into?
Creates an iterator from a value. Read more
The type of the elements being iterated over.
Which kind of iterator are we turning this into?
Creates an iterator from a value. Read more
This method tests for self and other values to be equal, and is used by ==.
This method tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.

Returns the difference of self and rhs (right hand side) as a new MultiSet<T, S>.

Examples
use mset::MultiSet;

let p: MultiSet<_> = vec![1, 2, 3, 3].into_iter().collect();
let q: MultiSet<_> = vec![3, 4, 5].into_iter().collect();

let mset = &p - &q;

let mut i = 0;
let expected = [1, 2, 3];
for (e, m) in &mset {
    assert!(expected.contains(e));
    i += (e * m);
}

assert_eq!(i, expected.iter().sum());
The resulting type after applying the - operator.

Auto Trait Implementations§

Blanket Implementations§

Gets the TypeId of self. Read more
Immutably borrows from an owned value. Read more
Mutably borrows from an owned value. Read more

Returns the argument unchanged.

Calls U::from(self).

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

The resulting type after obtaining ownership.
Creates owned data from borrowed data, usually by cloning. Read more
Uses borrowed data to replace owned data, usually by cloning. Read more
The type returned in the event of a conversion error.
Performs the conversion.
The type returned in the event of a conversion error.
Performs the conversion.