More Dart — Literally

Pub Package Build Status Code Coverage GitHub Issues GitHub Forks GitHub Stars GitHub License

A collection of extensively tested extensions that make Dart a better place:

Library Description
async Extensions to Stream.
cache Caching strategies and their expiry policy.
char_matcher Character classes, their composition, and operations on strings.
collection Extensions to Iterable and new collection types.
comparator Common comparators, and extensions to perform advanced operations.
diff Tools for comparing lists.
feature Information about the runtime environment.
functional Types and features known from functional programming.
graph Graph-theory objects and algorithms.
interval Continuous interval data type over a practical range.
math Common mathematical functions.
number Number types: fraction, complex, quaternion.
printer Fluent interface to configure sophisticated formatters.
temporal Extensions to DateTime and Duration types.
tuple Tuple extension methods on generic records.

And there are more to come ...

Highlights

Collections & Iterables

Powerful extensions and specialized data structures that complement dart:collection:

import 'package:more/collection.dart';

// Integer ranges with custom stepping
0.to(10, step: 2); // [0, 2, 4, 6, 8]

// Sliding windows and fixed chunks
[1, 2, 3, 4, 5].window(3); // [[1, 2, 3], [2, 3, 4], [3, 4, 5]]
[1, 2, 3, 4, 5].chunked(2); // [[1, 2], [3, 4], [5]]

// Combinatorics: combinations, permutations, and power sets
['a', 'b', 'c'].combinations(2); // [['a', 'b'], ['a', 'c'], ['b', 'c']]

// Rich collections: Multimaps, BiMaps, BitLists, and Sorted/Ordered lists
final multimap = ListMultimap<String, int>()
  ..add('even', 2)
  ..add('even', 4)
  ..add('odd', 1);
print(multimap['even']); // [2, 4]

Graph Theory & Algorithms

Flexible graph data structures with built-in pathfinding, search, and topological analysis:

import 'package:more/graph.dart';

// Create a directed weighted graph
final graph = Graph<String, num>.directed()
  ..addEdge('A', 'B', value: 4)
  ..addEdge('A', 'C', value: 2)
  ..addEdge('C', 'B', value: 1);

// Find shortest path using Dijkstra's algorithm
final path = graph.shortestPath('A', 'B');
print(path?.vertices); // ['A', 'C', 'B']
print(path?.cost); // 3

// Topological sort and cycle detection
final sorted = graph.topological('A');
final hasCycle = graph.hasCycle();

Numbers & Mathematics

Exact rational arithmetic, complex numbers, and extended math functions on integers:

import 'package:more/math.dart';
import 'package:more/number.dart';

// Exact rational arithmetic
final a = Fraction(1, 3);
final b = Fraction(1, 6);
print(a + b); // Fraction(1, 2)
print(Fraction.tryParse('3/4')); // Fraction(3, 4)

// Complex numbers & quaternions
final c = Complex(3, 4);
print(c.abs()); // 5.0

// Math extensions on int and BigInt
12.gcd(8); // 4
5.factorial(); // 120
17.isProbablyPrime; // true
123.digits(); // [3, 2, 1]

Composable Printers

A fluent, composable model to format strings, numbers, and dates without complex templates:

import 'package:more/printer.dart';

// Formatted numbers with padding, prefix, and precision
final currency = FixedNumberPrinter(precision: 2).before(r'$').padLeft(8);
print(currency(12.5)); // '  $12.50'

// Human-readable binary/decimal quantities
final human = HumanNumberPrinter.binary();
print(human(1024 * 1024 * 3)); // '3 Mi'

// Configurable date and time formatting
final date = DateTimePrinter.date();
print(date(DateTime(2025, 1, 15))); // '2025-01-15'

Temporal & Intervals

Fluent manipulation of dates, durations, and continuous intervals:

import 'package:more/interval.dart';
import 'package:more/temporal.dart';

// Truncate dates to specific units
final now = DateTime(2025, 5, 12, 14, 23, 45);
print(now.truncateTo(TimeUnit.hour)); // 2025-05-12 14:00:00.000

// Continuous interval operations
final intA = Interval(1, 5); // [1..5]
final intB = Interval(3, 7); // [3..7]
print(intA.intersection(intB)); // [3..5]

Unicode & Character Matching

Full Unicode 18.0.0 compliance featuring standard normalization algorithms and composable character classifiers:

import 'package:more/char_matcher.dart';
import 'package:more/collection.dart';

// Unicode Normalization (NFC, NFD, NFKC, NFKD)
'e\u0301le\u0300ve'.normalize(); // 'élève'
'①'.normalize(form: NormalizationForm.nfkc); // '1'
'ffi'.normalize(form: NormalizationForm.nfkc); // 'ffi'

// Match official Unicode categories, scripts, and properties
final greek = UnicodeCharMatcher.scriptGreek();
final whitespace = UnicodeCharMatcher.whiteSpace();

// Filter, collapse, and clean strings beyond basic ASCII
greek.retainFrom('Hello Ελληνικά!'); // 'Ελληνικά'
whitespace.collapseFrom('lots   of   spaces', ' '); // 'lots of spaces'

// Compose matchers with set operations
final latinOrDigits = UnicodeCharMatcher.scriptLatin() | CharMatcher.digit();
latinOrDigits.retainFrom('Hello 123! π'); // 'Hello123'

// Unicode-aware string splitting preserving surrogate pairs
'Dart 🎯'.toList(unicode: true); // ['D', 'a', 'r', 't', ' ', '🎯']

Caching Strategies

Self-loading asynchronous caches with LRU, FIFO, and duration-based expiry policies:

import 'package:more/cache.dart';

// Self-loading LRU cache with maximum size
final cache = Cache<String, int>.lru(
  loader: (key) => expensiveCalculation(key),
  maximumSize: 100,
);
final value = await cache.get('hello');

Misc

This library is open source, stable and well tested. Development happens on GitHub. Feel free to report issues or create a pull-request there. General questions are best asked on StackOverflow.

The package is hosted on dart packages. Up-to-date class documentation is created with every release.

Contributing

The goal of the library is to provide a loose collection of carefully curated utilities that are not provided by the Dart standard library. All features must be well tested. New features must have significant advantages over alternatives, such as code reduction, readability improvement, speed increase, memory reduction, or improved accuracy. In case of doubt, consider filing a feature request before filing a pull request.

History

This library started in April 2013 as I was working through the puzzles of Project Euler and encountered some missing features in Dart. Over time the code grew and became more useful in many other places, so I created this reusable library.

Some parts of this library are inspired by similar APIs in Google Guava (Google core libraries for Java) and Apache Commons (a repository of reusable Java components).

License

The MIT License, see LICENSE.

Libraries

async
Helpers to make async code better.
cache
Collection of different caching strategies and their expiry policy.
char_matcher
A first-class model of character classes, their composition and operations on strings.
collection
A collection of iterable extensions and new collection types: bi-map, bit-list, multi-set, set and list multi-map, range, and string.
comparator
Provides default Comparator constructors, and various static extension methods to modify and perform common operations on Comparator functions.
diff
Port of Python's difflib library to Dart providing tools for comparing lists.
feature
Information about the runtime environment.
functional
A collection of functional programming structures.
graph
Graph-theory objects and algorithms.
interval
Provides a continuous interval.
math
A collection of common mathematical functions.
more
More Dart — Literally.
number
Support for fractional and complex arithmetic.
pragma
Pragmas for Dart compilers.
printer
Provides a first-class model to convert objects to strings using composition and highly configurable formatting primitives.
temporal
Various extensions to the built-in date, time and duration objects.
tuple
Tuple extension methods on generic records.