Deequery is library for declarative/functional working with collections in Dart. Note: it used to be called Dart Query.
Query is a view on top of arbitrary
Iterable. It itself can be iterated.
It is designed to be used in a "pipeline" -- that is, a query is created, some operations are applied to it and finally a result is obtained. It looks like this:
var q = query(collection) // collection of numbers .filter((e) => e % 2 == 0) // only take even numbers .reject((e) => e < 0) // get rid of negative numbers .map((e) => e * 2) // double each number .skip(1) // get rid of the first element .take(2); // only take first 2 elements
In this case, the result is also a
var n = query(collection) // collection of numbers .filter((e) => e > 0) // only take positive numbers .findFirst((e) => e % 2 != 0); // find the first that is odd
In this case, the result is one element of the collection.
var b = query(collection) // collection of numbers .takeWhile((e) => e < 0) // only take negative numbers from the beginning .some((e) => e % 2 == 0); // find out if some of them is even
And finally, in this case the result is a
bool. So you see that
a pretty powerful vehicle for working with collections.
In all the examples above, we were using plain predicates (Dart functions). But Deequery also supports matchers from the Darmatch library, which can make the code even easier to understand.
Here are the examples above, rewritten using matchers:
var q = query(collection) .filter(even()) .reject(lessThan(0)) .map((e) => e * 2) .skip(1) .take(2); var n = query(collection) .filter(positive()) .findFirst(odd()); var b = query(collection) .takeWhile(negative()) .some(even());
Lazy and eager
query function we were using above is creating a lazy query -- meaning
that everything is computed lazily, only when needed and not before. This is
useful if the collection (or
Iterable) is computed dynamically, read from
file or network, etc. It also means that whatever changes you make to the
collection after creating the query, they are always visible when the query
is actually iterated.
On the other hand, you can use an
eagerQuery function which performs all
operations immediatelly. It copies the original collection so that it can
modify it in place. For smaller collections that are already fully read into
memory, this will usually be faster, but further changes to the collection
won't be reflected.
(Note that sometimes, the lazy query can get converted to eager one. See the documentation for more informations about when this happens.)