flinq 1.0.0

flinq #

Build codecov Pub GitHub GitHub stars

Extended capabilities for collections. It's a bunch of shortcuts to avoid unnecesary boilerplate work with collections.

Getting Started #

This package will help you to reduce the amount of boilerplate code by adding folowing extensions for Iterables:

  • getter firstOrNull and method firstOrNullWhere for getting first value, and if it will not be found returns null

  • getter lastOrNull and method lastOrNullWhere for getting last value, and if it will not be found returns null

  • getter singleOrNull and method singleOrNullWhere for getting single value, and if it will not be found returns null, and if there will be too many elements it'll throw the StateError

  • method mapList, which maps collection and casts it to List

  • method whereList, which filters collection and casts it to List

  • method mapWhereList, which maps collection, then filters it and then casts it to List

  • method whereMapList, which filters collection, then maps collection and then casts it to List

  • getter notNull for getting only not null values from the collection

  • getter min/minOrNull and max/maxOrNull for getting minimal or maximal value from collection of Comparables

  • method minWhere/minOrNullWhere and maxWhere/maxOrNullWhere for getting minimal or maximal value from filtered collection of Comparables

  • getter sum and average for getting sum and average from collection of nums

  • method sumWhere and averageWhere for getting sum and average from filtered collection of nums

  • getter distinct and method distinctWhere which will return List with unique values in collection

  • method union and unionWhere which will return List with union of two collections with only unique values in resulting collection

  • method intersection and intersectionWhere which will return List with elements that contains both collections with only unique values in resulting collection

  • method difference and differenceWhere which will return List with difference between two collections with only unique values in resulting collection

Examples #

Iterable extension can be used like this:

Common #

  • firstOrNull and firstOrNullWhere
final firstOrNull = [].firstOrNull; // null
// or
final firstOrNull = [3, 6, 2, 7, 9].firstOrNullWhere((item) => item > 10); // null
  • lastOrNull and lastOrNullWhere
final lastOrNull = [].lastOrNull; // null
// or
final lastOrNull = [3, 6, 2, 7, 9].lastOrNullWhere((item) => item > 10); // null
  • singleOrNull and singleOrNullWhere
final singleOrNull = [].singleOrNull; // null
// or
final singleOrNull = [3, 6, 2, 7, 9].singleOrNullWhere((item) => item > 3); // null
  • mapList
List<double> mappedList = [3, 6, 2, 7, 9].mapList((item) => item.toDouble());
  • whereList
List<int> filteredList = [3, 6, 2, 7, 9].whereList((item) => item > 4);
  • whereMapList
List<double> filteredMappedList = [3, 6, 2, 7, 9].whereMapList((item) => item > 4, (item) => item.toDouble());
  • mapWhereList
List<double> mappedFilteredList = [3, 6, 2, 7, 9].mapWhereList((item) => item.toDouble(), (item) => item > 4);
  • notNull
Iterable<int> notNullIterable = [3, 6, 2, null, 7, 9].notNull;

Comparable #

  • min and minOrNull
final min = [3, 6, 2, 7, 9].min; // 2
// or
final min = [].minOrNull; // null
  • minWhere and minOrNullWhere
final min = [3, 6, 2, 7, 9].minWhere((_) => _ > 4); // 6
// or
final min = [3, 2].minOrNullWhere((_) => _ > 4); // null
  • max and maxOrNull
final max = [3, 6, 2, 7, 9].max; // 9
// or
final max = [].maxOrNull; // null
  • maxWhere and maxOrNullWhere
final max = [3, 6, 2, 7, 9].maxWhere((_) => _ < 4); // 3
// or
final max = [3, 2].maxOrNullWhere((_) => _ > 4); // null
  • group
final collection = [
    Pet("rat", "Mike"),
    Pet("dog", "Rex"),
    Pet("cat", "Lucy"),
];

/*
<bool, List<Pet>>{
    true: [
        Pet("rat", "Mike"),
        Pet("cat", "Lucy"),
    ],
    false: [
        Pet("dog", "Rex"),
    ],
}
*/
final group = collection.group((item) => item.name.endsWith('at'));
  • groupMap
final collection = [
    Pet("rat", "Mike"),
    Pet("dog", "Rex"),
    Pet("cat", "Lucy"),
];

/*
<bool, int>{
    true: 2,
    false: 1,
}
*/
final groupMapped = collection.groupMap(
      (item) => item.name.endsWith('at'), (group) => group.length);

Math #

  • sum
final sum = [3, 6, 2, 7, 9].sum; // 27
  • average
final average = [1, 3, 5, 7, 4, 4].average; // 4
  • sumWhere
final sum = [3, 6, 2, 7, 9].sumWhere((_) => _ > 4); // 22
  • averageWhere
final average = [1, 3, 5, 7, 4, 4].averageWhere((_) => _ > 4); // 6

Set #

  • distinct
final collectionOne = [2, 5, 8, 2];

final distinctCollection = collectionOne.distinct; // [2, 5, 8]
  • distinctWhere
final collectionOne = [2, 5, 8, 2];

final distinctCollection = collectionOne.distinctWhere((_) => _ > 4); // [5, 8]
  • union
final collectionOne = [2, 5, 8, 2];
final collectionTwo = [1, 3, 5, 7];

final unitedCollection = collectionOne.union(collectionTwo); // [2, 5, 8, 1, 3, 7]
  • unionWhere
final collectionOne = [2, 5, 8, 2];
final collectionTwo = [1, 3, 5, 7];

final unitedCollection = collectionOne.unionWhere(collectionTwo, (_) => _ > 4); // [5, 8, 7]
  • intersection
final collectionOne = [2, 5, 8, 2];
final collectionTwo = [1, 3, 5, 7];

final intersectedCollection = collectionOne.intersection(collectionTwo); // [5]
  • intersectionWhere
final collectionOne = [2, 5, 8, 2];
final collectionTwo = [1, 3, 5, 7];

final intersectedCollection = collectionOne.intersectionWhere(collectionTwo, (_) => _ < 4); // []
  • difference
final collectionOne = [2, 5, 8, 2];
final collectionTwo = [1, 3, 5, 7];

final differedCollection = collectionOne.difference(collectionTwo); // [2, 8]
// or
final differedCollection = collectionTwo.difference(collectionOne); // [1, 3, 7]
  • differenceWhere
final collectionOne = [2, 5, 8, 2];
final collectionTwo = [1, 3, 5, 7];

final differedCollection = collectionOne.differenceWhere(collectionTwo, (_) => _ < 4); // [2]
// or
final differedCollection = collectionTwo.differenceWhere(collectionOne, (_) => _ < 4); // [1, 3]

Feature requests #

Feel free to post feature requests here.

Changelog #

[1.0.0]

  • Added distinctWhere, unionWhere, intersectionWhere, differenceWhere extensions
  • Added minWhere, maxWhere, minOrNullWhere, maxOrNullWhere extensions

[0.5.0]

  • Added whereList, whereMapList, mapWhereList, notNull extensions
  • Added sumWhere, averageWhere extensions
  • Redo examples

[0.4.1]

  • Migrated to GitHub
  • Minor refactorings
  • Updated homepage link

[0.4.0]

  • Added group and groupMap methods
  • Updated example

[0.3.0]

  • Added tests
  • Updated README

[0.2.0]

  • Moved List set extensions to Iterable set extensions
  • Moved List common extensions to Iterable common extensions
  • Added examples

[0.1.0]

  • Created Iterable common extensions
  • Created Iterable comparable extensions
  • Created Iterable math extensions
  • Created List common extensions
  • Created List set extensions

example/README.md

flinq_example #

Demonstrates how to use the flinq package.

Usage #

Pet model #

import 'package:flinq/flinq.dart';

class Pet implements Comparable<Pet> {
  const Pet(this.name, this.nickname);

  final String name;
  final String nickname;

  @override
  int compareTo(Pet other) => name.compareTo(other.name);

  @override
  bool operator ==(Object other) =>
      other is Pet ? other.name == name && other.nickname == nickname : false;

  @override
  int get hashCode => name.hashCode + nickname.hashCode;

  @override
  String toString() => '$name ($nickname)';
}

Iterable Common #


final _emptyCollection = [];
final _singleItemCollection = ["item"];
final _numCollection = [3, 6, 2, 7, 9];
final _comparableCollection = [
  Pet("rat", "Mike"),
  Pet("dog", "Rex"),
  Pet("cat", "Lucy"),
];

void _firstOrNull() {
  print('---- firstOrNull ----\n');

  var result = _emptyCollection.firstOrNull; // []
  assert(result == null); // true
  print(result?.toString());

  result = _singleItemCollection.firstOrNull; // ["item"]
  assert(result == "item"); // true
  print(result?.toString());

  result = _numCollection.firstOrNull; // [3, 6, 2, 7, 9]
  assert(result == 3); // true
  print(result?.toString());

  result = _comparableCollection
      .firstOrNull; // [ Pet("rat", "Mike"), Pet("dog", "Rex"), Pet("cat", "Lucy") ]
  assert(result == Pet("rat", "Mike")); // true
  print(result?.toString());

  print('---- ----------- ----\n');
}

void _lastOrNull() {
  print('---- lastOrNull ----\n');

  var result = _emptyCollection.lastOrNull; // []
  assert(result == null); // true
  print(result?.toString());

  result = _singleItemCollection.lastOrNull; // ["item"]
  assert(result == "item"); // true
  print(result?.toString());

  result = _numCollection.lastOrNull; // [3, 6, 2, 7, 9]
  assert(result == 9); // true
  print(result?.toString());

  result = _comparableCollection
      .lastOrNull; // [ Pet("rat", "Mike"), Pet("dog", "Rex"), Pet("cat", "Lucy") ]
  assert(result == Pet("cat", "Lucy")); // true
  print(result?.toString());

  print('---- ---------- ----\n');
}

void _singleOrNull() {
  print('---- singleOrNull ----\n');

  var result = _emptyCollection.singleOrNull; // []
  assert(result == null); // true
  print(result?.toString());

  result = _singleItemCollection.singleOrNull; // ["item"]
  assert(result == "item"); // true
  print(result?.toString());

  try {
    result = _numCollection.singleOrNull; // [3, 6, 2, 7, 9]
    assert(false);
    print(result?.toString());
  } catch (e) {
    assert(e is StateError); // true (Too many elements)
    print(e.toString());
  }

  try {
    result = _comparableCollection
        .singleOrNull; // [ Pet("rat", "Mike"), Pet("dog", "Rex"), Pet("cat", "Lucy") ]
    assert(false);
    print(result?.toString());
  } catch (e) {
    assert(e is StateError); // true (Too many elements)
    print(e.toString());
  }

  print('---- ------------ ----\n');
}

void _firstOrNullWhere() {
  print('---- firstOrNullWhere ----\n');

  var result = _emptyCollection.firstOrNullWhere((item) => item != null); // []
  assert(result == null); // true
  print(result?.toString());

  result = _singleItemCollection
      .firstOrNullWhere((item) => item != "item"); // ["item"]
  assert(result == null); // true
  print(result?.toString());

  result =
      _numCollection.firstOrNullWhere((item) => item > 3); // [3, 6, 2, 7, 9]
  assert(result == 6); // true
  print(result?.toString());

  result = _comparableCollection.firstOrNullWhere(
    (item) => item.name.contains("at"),
  ); // [ Pet("rat", "Mike"), Pet("dog", "Rex"), Pet("cat", "Lucy") ]
  assert(result == Pet("rat", "Mike")); // true
  print(result?.toString());

  print('---- ---------------- ----\n');
}

void _lastOrNullWhere() {
  print('---- lastOrNullWhere ----\n');

  var result = _emptyCollection.lastOrNullWhere((item) => item != null); // []
  assert(result == null); // true
  print(result?.toString());

  result = _singleItemCollection
      .lastOrNullWhere((item) => item != "item"); // ["item"]
  assert(result == null); // true
  print(result?.toString());

  result =
      _numCollection.lastOrNullWhere((item) => item > 3); // [3, 6, 2, 7, 9]
  assert(result == 9); // true
  print(result?.toString());

  result = _comparableCollection.lastOrNullWhere(
    (item) => item.name.contains("at"),
  ); // [ Pet("rat", "Mike"), Pet("dog", "Rex"), Pet("cat", "Lucy") ]
  assert(result == Pet("cat", "Lucy")); // true
  print(result?.toString());

  print('---- --------------- ----\n');
}

void _singleOrNullWhere() {
  print('---- singleOrNullWhere ----\n');

  var result = _emptyCollection.singleOrNullWhere((item) => item != null); // []
  assert(result == null); // true
  print(result?.toString());

  result = _singleItemCollection
      .singleOrNullWhere((item) => item != "item"); // ["item"]
  assert(result == null); // true
  print(result?.toString());

  result =
      _numCollection.singleOrNullWhere((item) => item < 3); // [3, 6, 2, 7, 9]
  assert(result == 2); // true
  print(result?.toString());

  result = _comparableCollection.singleOrNullWhere(
    (item) => item.name == "rat",
  ); // [ Pet("rat", "Mike"), Pet("dog", "Rex"), Pet("cat", "Lucy") ]
  assert(result == Pet("rat", "Mike")); // true
  print(result?.toString());

  print('---- ----------------- ----\n');
}

void _mapList() {
  print('---- mapList ----\n');

  final result = _numCollection.mapList((item) => item.toDouble());
  assert(result is List<double>);
  print(result.toString());

  print('---- ------- ----\n');
}

void _whereList() {
  print('---- whereList ----\n');

  final result = _numCollection.whereList((_) => _ > 4);
  assert(result == <int>[6, 7, 9]);
  print(result.toString());

  print('---- --------- ----\n');
}

void _whereMapList() {
  print('---- whereMapList ----\n');

  final result = _numCollection.whereMapList((_) => _ > 4, (_) => _.toDouble());
  assert(result == <double>[6, 7, 9]);
  print(result.toString());

  print('---- ------------ ----\n');
}

void _mapWhereList() {
  print('---- mapWhereList ----\n');

  final result =
      _numCollection.mapWhereList<double>((_) => _.toDouble(), (_) => _ > 4);
  assert(result == <double>[6, 7, 9]);
  print(result.toString());

  print('---- ------------ ----\n');
}

void _notNull() {
  print('---- notNull ----\n');

  final numCollection = [null, ..._numCollection, null];

  final result = numCollection.notNull;
  assert(result.toString() == _numCollection.toString());
  print(result.toString());

  print('---- ------- ----\n');
}

void iterableCommonTest() {
  _firstOrNull();
  _lastOrNull();
  _singleOrNull();
  _firstOrNullWhere();
  _lastOrNullWhere();
  _singleOrNullWhere();
  _mapList();
  _whereList();
  _whereMapList();
  _mapWhereList();
  _notNull();
}

Iterable Comparable #


final _emptyCollection = <Pet>[];
final _collection = [
  Pet("rat", "Mike"),
  Pet("dog", "Rex"),
  Pet("cat", "Lucy"),
];

void _min() {
  print('---- min ----\n');

  // [ Pet("rat", "Mike"), Pet("dog", "Rex"), Pet("cat", "Lucy") ]
  var result = _collection.min;
  assert(result == Pet("cat", "Lucy")); // true
  print(result?.toString());

  try {
    result = _emptyCollection.min; // []
    assert(false);
    print(result?.toString());
  } catch (e) {
    assert(e is StateError); // true (No element)
    print(e.toString());
  }

  print('---- --- ----\n');
}

void _minWhere() {
  print('---- minWhere ----\n');

  // [ Pet("rat", "Mike"), Pet("dog", "Rex"), Pet("cat", "Lucy") ]
  var result = _collection.minWhere((_) => _.name != "cat");
  assert(result == Pet("dog", "Rex")); // true
  print(result?.toString());

  try {
    result = _collection.minWhere((_) => _.name == "rabbit"); // []
    assert(false);
    print(result?.toString());
  } catch (e) {
    assert(e is StateError); // true (No element)
    print(e.toString());
  }

  print('---- --- ----\n');
}

void _minOrNull() {
  print('---- minOrNull ----\n');

  // [ Pet("rat", "Mike"), Pet("dog", "Rex"), Pet("cat", "Lucy") ]
  var result = _collection.minOrNull;
  assert(result == Pet("cat", "Lucy")); // true
  print(result?.toString());

  result = _emptyCollection.minOrNull; // []
  assert(result == null); // true
  print(result?.toString());

  print('---- --------- ----\n');
}

void _minOrNullWhere() {
  print('---- minOrNullWhere ----\n');

  // [ Pet("rat", "Mike"), Pet("dog", "Rex"), Pet("cat", "Lucy") ]
  var result = _collection.minOrNullWhere((_) => _.name != "cat");
  assert(result == Pet("dog", "Rex")); // true
  print(result?.toString());

  result = _emptyCollection.minOrNullWhere((_) => _.name == "rabbit"); // []
  assert(result == null); // true
  print(result?.toString());

  print('---- --------- ----\n');
}

void _max() {
  print('---- max ----\n');

  // [ Pet("rat", "Mike"), Pet("dog", "Rex"), Pet("cat", "Lucy") ]
  var result = _collection.max;
  assert(result == Pet("rat", "Mike")); // true
  print(result?.toString());

  try {
    result = _emptyCollection.max; // []
    assert(false);
    print(result?.toString());
  } catch (e) {
    assert(e is StateError); // true (No element)
    print(e.toString());
  }

  print('---- --- ----\n');
}

void _maxWhere() {
  print('---- maxWhere ----\n');

  // [ Pet("rat", "Mike"), Pet("dog", "Rex"), Pet("cat", "Lucy") ]
  var result = _collection.maxWhere((_) => _.name != "cat");
  assert(result == Pet("rat", "Mike")); // true
  print(result?.toString());

  try {
    result = _collection.maxWhere((_) => _.name == "rabbit"); // []
    assert(false);
    print(result?.toString());
  } catch (e) {
    assert(e is StateError); // true (No element)
    print(e.toString());
  }

  print('---- --- ----\n');
}

void _maxOrNull() {
  print('---- maxOrNull ----\n');

  // [ Pet("rat", "Mike"), Pet("dog", "Rex"), Pet("cat", "Lucy") ]
  var result = _collection.maxOrNull;
  assert(result == Pet("rat", "Mike")); // true
  print(result?.toString());

  result = _emptyCollection.maxOrNull; // []
  assert(result == null); // true
  print(result?.toString());

  print('---- --------- ----\n');
}

void _maxOrNullWhere() {
  print('---- maxOrNullWhere ----\n');

  // [ Pet("rat", "Mike"), Pet("dog", "Rex"), Pet("cat", "Lucy") ]
  var result = _collection.maxOrNullWhere((_) => _.name != "cat");
  assert(result == Pet("rat", "Mike")); // true
  print(result?.toString());

  result = _emptyCollection.maxOrNullWhere((_) => _.name == "rabbit"); // []
  assert(result == null); // true
  print(result?.toString());

  print('---- --------- ----\n');
}

void _group() {
  print('---- group ----\n');

  final result = _collection.group((item) => item.name.endsWith('at'));
  assert(result.toString() ==
      <bool, List<Pet>>{
        true: [
          Pet("rat", "Mike"),
          Pet("cat", "Lucy"),
        ],
        false: [
          Pet("dog", "Rex"),
        ],
      }.toString()); // true
  print(result?.toString());

  print('---- ----- ----\n');
}

void _groupMap() {
  print('---- groupMap ----\n');

  final result = _collection.groupMap(
      (item) => item.name.endsWith('at'), (group) => group.length);
  assert(result.toString() ==
      <bool, int>{
        true: 2,
        false: 1,
      }.toString()); // true
  print(result?.toString());

  print('---- -------- ----\n');
}

void iterableComparableTest() {
  _min();
  _minWhere();
  _minOrNull();
  _minOrNullWhere();
  _max();
  _maxWhere();
  _maxOrNull();
  _maxOrNullWhere();
  _group();
  _groupMap();
}

Iterable Math #

void iterableMathTest() {
  print('---- iterable math ----\n');

  final emptyCollection = <num>[];
  final oneCollection = [8]; // 8
  final manyCollection = [1, 3, 5, 7, 8, 2, 4]; // 30

  assert(emptyCollection.sum == 0); // true
  print(emptyCollection.sum);
  assert(oneCollection.sum == 8); // true
  print(oneCollection.sum);
  assert(manyCollection.sum == 30); // true
  print(manyCollection.sum);

  assert(emptyCollection.average == 0); // true
  print(emptyCollection.average);
  assert(oneCollection.average == 8); // true
  print(oneCollection.average);
  assert(manyCollection.average == 30 / 7); // true
  print(manyCollection.average);

  assert(emptyCollection.sumWhere((_) => _ > 4) == 0); // true
  print(emptyCollection.sumWhere((_) => _ > 4));
  assert(oneCollection.sumWhere((_) => _ > 4) == 8); // true
  print(oneCollection.sumWhere((_) => _ > 4));
  assert(manyCollection.sumWhere((_) => _ > 4) == 20); // true
  print(manyCollection.sumWhere((_) => _ > 4));

  assert(emptyCollection.averageWhere((_) => _ > 4) == 0); // true
  print(emptyCollection.averageWhere((_) => _ > 4));
  assert(oneCollection.averageWhere((_) => _ > 4) == 8); // true
  print(oneCollection.averageWhere((_) => _ > 4));
  assert(manyCollection.averageWhere((_) => _ > 4) == 20 / 3); // true
  print(manyCollection.averageWhere((_) => _ > 4));

  print('---- ------------- ----\n');
}

Iterable Set #

void iterableSetTest() {
  print('---- iterable set ----\n');

  final collectionOne = [2, 5, 8, 2];
  final collectionTwo = [1, 3, 5, 7];

  print(collectionOne.distinct); // [2, 5, 8]
  print(collectionOne.union(collectionTwo)); // [2, 5, 8, 1, 3, 7]
  print(collectionOne.intersection(collectionTwo)); // [5]
  print(collectionOne.difference(collectionTwo)); // [2, 8]
  print(collectionTwo.difference(collectionOne)); // [1, 3, 7]

  print(collectionOne.distinctWhere((_) => _ > 4)); // [2, 5, 8]
  print(collectionOne.unionWhere(collectionTwo, (_) => _ > 4)); // [5, 8, 7]
  print(collectionOne.intersectionWhere(collectionTwo, (_) => _ < 4)); // []
  print(collectionOne.differenceWhere(collectionTwo, (_) => _ < 4)); // [2]
  print(collectionTwo.differenceWhere(collectionOne, (_) => _ < 4)); // [1, 3]
 
  print('---- ------------ ----\n');
}

Getting Started #

For help getting started with Dart, view online documentation, which offers tutorials, samples, guidance, and a full API reference.

Use this package as a library

1. Depend on it

Add this to your package's pubspec.yaml file:


dependencies:
  flinq: ^1.0.0

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:flinq/flinq.dart';
  
Popularity:
Describes how popular the package is relative to other packages. [more]
65
Health:
Code health derived from static analysis. [more]
100
Maintenance:
Reflects how tidy and up-to-date the package is. [more]
100
Overall:
Weighted score of the above. [more]
82
Learn more about scoring.

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

  • Dart: 2.7.1
  • pana: 0.13.5

Dependencies

Package Constraint Resolved Available
Direct dependencies
Dart SDK >=2.6.0 <3.0.0
Dev dependencies
pedantic ^1.8.0
test ^1.9.4