compare 0.1.0

Experimental comparators for collections to be generic over

Crate compare [] [src]

Comparators.

A comparator is any type that implements the Compare trait, which imposes a total order. Its compare method accepts two values, which may be of the same type or different types, and returns an ordering on them.

Comparators are useful for parameterizing the behavior of sort methods and certain data structures.

The most basic comparator is Natural, which simply delegates to the type's implementation of Ord:

use compare::{Compare, natural};
use std::cmp::Ordering::{Less, Equal, Greater};

let a = &1;
let b = &2;

let cmp = natural();
assert_eq!(cmp.compare(a, b), Less);
assert_eq!(cmp.compare(b, a), Greater);
assert_eq!(cmp.compare(a, a), Equal);

There are convenience methods for checking each of the six relations:

use compare::{Compare, natural};

let a = &1;
let b = &2;

let cmp = natural();
assert!(cmp.compares_lt(a, b));
assert!(cmp.compares_le(a, b));
assert!(cmp.compares_ge(b, a));
assert!(cmp.compares_gt(b, a));
assert!(cmp.compares_eq(a, a));
assert!(cmp.compares_ne(a, b));

The Compare trait also provides default methods that consume a comparator to produce a new one with different behavior, similar to iterator adaptors. For example, all comparators can be reversed:

use compare::{Compare, natural};
use std::cmp::Ordering::Greater;

let cmp = natural().rev();
assert_eq!(cmp.compare(&1, &2), Greater);

It is possible to implement a comparator that is not based on the natural ordering of a type by using a closure of type Fn(&L, &R) -> Ordering. For example, slices can be compared by their length instead of their contents:

use compare::Compare;
use std::cmp::Ordering::{Less, Greater};

let a = [1, 2, 3];
let b = [4, 5];

let cmp = |l: &[i32], r: &[i32]| l.len().cmp(&r.len());
assert_eq!(cmp.compare(&a, &b), Greater);

let cmp = cmp.rev();
assert_eq!(cmp.compare(&a, &b), Less);

Comparators can be combined lexicographically in order to compare values first by one key, then, if the first keys were equal, by another:

use compare::Compare;
use std::cmp::Ordering::{Less, Equal, Greater};

struct Pet { name: &'static str, age: u8 }

let fido4 = &Pet { name: "Fido", age: 4 };
let ruff2 = &Pet { name: "Ruff", age: 2 };
let fido3 = &Pet { name: "Fido", age: 3 };

let name_cmp = |l: &Pet, r: &Pet| l.name.cmp(r.name);
assert_eq!(name_cmp.compare(fido4, ruff2), Less);
assert_eq!(name_cmp.compare(fido4, fido3), Equal);
assert_eq!(name_cmp.compare(ruff2, fido3), Greater);

let age_cmp = |l: &Pet, r: &Pet| l.age.cmp(&r.age);
assert_eq!(age_cmp.compare(fido4, ruff2), Greater);
assert_eq!(age_cmp.compare(fido4, fido3), Greater);
assert_eq!(age_cmp.compare(ruff2, fido3), Less);

let name_age_cmp = name_cmp.then(age_cmp);
assert_eq!(name_age_cmp.compare(fido4, ruff2), Less);
assert_eq!(name_age_cmp.compare(fido4, fido3), Greater);
assert_eq!(name_age_cmp.compare(ruff2, fido3), Greater);

It is often repetitive to compare two values of the same type by the same key, so the key-extraction logic can be factored out, simplifying the previous example:

use compare::{Compare, Extract};
use std::cmp::Ordering::{Less, Greater};

struct Pet { name: &'static str, age: u8 }

let fido4 = &Pet { name: "Fido", age: 4 };
let ruff2 = &Pet { name: "Ruff", age: 2 };
let fido3 = &Pet { name: "Fido", age: 3 };

let name_age_cmp = Extract::new(|p: &Pet| p.name)
             .then(Extract::new(|p: &Pet| p.age));

assert_eq!(name_age_cmp.compare(fido4, ruff2), Less);
assert_eq!(name_age_cmp.compare(fido4, fido3), Greater);
assert_eq!(name_age_cmp.compare(ruff2, fido3), Greater);

Structs

Borrowing

A comparator that borrows its parameters before comparing them.

Extract

A comparator that extracts a sort key from a value.

Natural

A comparator that delegates to Ord.

Rev

A comparator that reverses the ordering of another.

Swap

A comparator that swaps another's parameters, maintaining the underlying ordering.

Then

A comparator that lexicographically combines two others.

Traits

Compare

A comparator imposing a total order.

Functions

max

Returns the maximum of two values according to the given comparator, or r if they are equal.

min

Returns the minimum of two values according to the given comparator, or l if they are equal.

natural

Returns a comparator that delegates to Ord.