# contrast2 #

Utilities for comparing (and contrast2ing) dart values:

• Comparator combinators (by/compound/reverse/lexicographic/nullsFirst/nullsLast)
• Comparison operator mixin (Quantity)(<, <=, ==, >, >=)
• Find extrema of Comparables and Iterables (min/max/minOf/maxOf)
• Test and obtain clamped comparables (clamp/between)
• Test and obtain sorted iterables (sorted/isOrdered/isStrictlyOrdered)

#Example

``````
import 'package:contrast2/contrast2.dart';
import 'dart:math' as math;

main() {

// Easily define comparison operators (see Point class below).
assert(Point.ZERO < Point.UNIT);
assert(Point.UNIT >= Point.ZERO);
assert(Point.ZERO == new Point(0, 0));

// Find extrema of arbitrary comparables.
// (dart:math's min/max only work with numbers)
assert(min(Point.ZERO, Point.UNIT) == Point.ZERO);
assert(max(Point.ZERO, Point.UNIT) == Point.UNIT);
assert(clamp(new Point(1, 2), Point.ZERO, Point.UNIT) == Point.UNIT);
assert(between(new Point(0.5, 0.5), Point.ZERO, Point.UNIT));

// Find extrema of iterables.
var points = [Point.UNIT, new Point(1, 2), Point.ZERO, new Point(0, 1)];
assert(minOf(points) == Point.ZERO);
assert(maxOf(points) == new Point(1, 2));

// Sort into a new List easily ( vs. iterable.toList()..sort() ).
var sortedPoints = sorted(points);

// Check ordering of iterables.
assert(isOrdered(sortedPoints));
assert(isStrictlyOrdered(sortedPoints));

// Define comparators using combinator helpers...

// By key function
var byMagnitude = by((point) => point.magnitude);
assert(max(Point.ZERO, new Point(-1, -1),
compare: byMagnitude) == new Point(-1, -1));

// Compound
assert(max(Point.ZERO, new Point(-1, -1),
compare: compound([byMagnitude, Comparable.compare])) == new Point(-1, -1));

// Reversed
assert(max(Point.ZERO, Point.UNIT, compare: reverse()) == Point.ZERO);

// Lexicographic
assert(min([Point.ZERO, Point.UNIT], [Point.ZERO, new Point(2, 2)],
compare: lexicographic()).last == Point.UNIT);

// Null safe
var maybePoints = [Point.UNIT, null, Point.ZERO, null];
assert(sorted(maybePoints, compare: nullsFirst()).first == null);
assert(sorted(maybePoints, compare: nullsLast()).last == null);
}

// Mixin `Comparable`-based comparison operators with `Quantity`.
class Point extends Object with Quantity<Point> {

static Point ZERO = new Point(0, 0);
static Point UNIT = new Point(1, 1);

final num x, y;

num get magnitude => math.sqrt(x*x + y*y);

Point(this.x, this.y);

// Use comparator combinators`compound` and `by`.
static final _comparator = compound([by((p) => p.x), by((p) => p.y)]);

int compareTo(Point other) => _comparator(this, other);

toString() => '(\$x, \$y)';
}
``````

example/example.dart

``````import 'package:contrast2/contrast2.dart';
import 'dart:math' as math;

main() {
// Easily define comparison operators (see Point class below).
assert(Point.ZERO < Point.UNIT);
assert(Point.UNIT >= Point.ZERO);
assert(Point.ZERO == new Point(0, 0));

// Find extrema of arbitrary comparables.
// (dart:math's min/max only work with numbers)
assert(min(Point.ZERO, Point.UNIT) == Point.ZERO);
assert(max(Point.ZERO, Point.UNIT) == Point.UNIT);
assert(clamp(new Point(1, 2), Point.ZERO, Point.UNIT) == Point.UNIT);
assert(between(new Point(0.5, 0.5), Point.ZERO, Point.UNIT));

// Find extrema of iterables.
var points = [Point.UNIT, new Point(1, 2), Point.ZERO, new Point(0, 1)];
assert(minOf(points) == Point.ZERO);
assert(maxOf(points) == new Point(1, 2));

// Sort into a new List easily ( vs. iterable.toList()..sort() ).
var sortedPoints = sorted(points);

// Check ordering of iterables.
assert(isOrdered(sortedPoints));
assert(isStrictlyOrdered(sortedPoints));

// Define comparators using combinator helpers...

// By key function
var byMagnitude = by((point) => point.magnitude);
assert(max(Point.ZERO, new Point(-1, -1), compare: byMagnitude) ==
new Point(-1, -1));

// Compound
assert(max(Point.ZERO, new Point(-1, -1),
compare: compound([byMagnitude, Comparable.compare])) ==
new Point(-1, -1));

// Reversed
assert(max(Point.ZERO, Point.UNIT, compare: reverse()) == Point.ZERO);

// Lexicographic
// assert(min([Point.ZERO, Point.UNIT], [Point.ZERO, new Point(2, 2)],
//     compare: lexicographic()).last == Point.UNIT);

// Null safe
var maybePoints = [Point.UNIT, null, Point.ZERO, null];
assert(sorted(maybePoints, compare: nullsFirst()).first == null);
assert(sorted(maybePoints, compare: nullsLast()).last == null);
}

// Mixin `Comparable`-based comparison operators with `Quantity`.
class Point extends Object with Quantity<Point> {
static Point ZERO = new Point(0, 0);
static Point UNIT = new Point(1, 1);

final num x, y;

num get magnitude => math.sqrt(x * x + y * y);

Point(this.x, this.y);

// Use comparator combinators`compound` and `by`.
static final _comparator = compound([by((p) => p.x), by((p) => p.y)]);

int compareTo(Point other) => _comparator(this, other);

toString() => '(\$x, \$y)';
}
``````

## Use this package as a library

### 1. Depend on it

``````
dependencies:
contrast2: ^0.2.0+1

``````

### 2. Install it

You can install packages from the command line:

with pub:

``````
\$ pub get

``````

with Flutter:

``````
\$ flutter pub get

``````

Alternatively, your editor might support `pub get` or `flutter pub get`. Check the docs for your editor to learn more.

### 3. Import it

Now in your Dart code, you can use:

``````
import 'package:contrast2/contrast2.dart';
``````
 Popularity: Describes how popular the package is relative to other packages. [more] 0 Health: Code health derived from static analysis. [more] 87 Maintenance: Reflects how tidy and up-to-date the package is. [more] 20 Overall: Weighted score of the above. [more] 30

We analyzed this package on Apr 8, 2020, and provided a score, details, and suggestions below. Analysis was completed with status completed using:

• Dart: 2.7.1
• pana: 0.13.6

#### Health suggestions

Fix `lib/src/extrema.dart`. (-5.84 points)

Analysis of `lib/src/extrema.dart` reported 12 hints, including:

line 3 col 1: Prefer using /// for doc comments.

line 7 col 50: Use `=` to separate a named parameter from its default value.

line 10 col 1: Prefer using /// for doc comments.

line 14 col 50: Use `=` to separate a named parameter from its default value.

line 17 col 1: Prefer using /// for doc comments.

Fix `lib/src/comparators.dart`. (-3.45 points)

Analysis of `lib/src/comparators.dart` reported 7 hints, including:

line 3 col 1: Prefer using /// for doc comments.

line 14 col 1: Prefer using /// for doc comments.

line 28 col 11: Unnecessary new keyword.

line 35 col 1: Prefer using /// for doc comments.

line 44 col 1: Prefer using /// for doc comments.

Fix `lib/src/ordered.dart`. (-1.99 points)

Analysis of `lib/src/ordered.dart` reported 4 hints:

line 4 col 1: Prefer using /// for doc comments.

line 9 col 37: Use `=` to separate a named parameter from its default value.

line 12 col 1: Prefer using /// for doc comments.

line 17 col 37: Use `=` to separate a named parameter from its default value.

Fix `lib/src/sorted.dart`. (-1.99 points)

Analysis of `lib/src/sorted.dart` reported 4 hints:

line 3 col 1: Prefer using /// for doc comments.

line 7 col 40: Use `=` to separate a named parameter from its default value.

line 8 col 22: Use `=` to separate a named parameter from its default value.

line 9 col 5: Unnecessary new keyword.

Fix `lib/contrast2.dart`. (-0.50 points)

Analysis of `lib/contrast2.dart` reported 1 hint:

line 2 col 1: Prefer using /// for doc comments.

#### Maintenance issues and suggestions

Provide a file named `CHANGELOG.md`. (-20 points)

Changelog entries help developers follow the progress of your package. See the example generated by `stagehand`.

Package is getting outdated. (-59.73 points)

The package was last published 83 weeks ago.

#### Dependencies

Package Constraint Resolved Available
Direct dependencies
Dart SDK >=2.0.0-dev.60.2 <3.0.0
Dev dependencies
quiver ^2.0.0
test 1.3.0