This photo is a tribute to Kallehallden, who loves programming and keeps a curious mind

Old iron remember to forward, Brother Cat will present more Flutter good articles ~~~~

Wechat Flutter research group Ducafecat

The cat said

I have no time to record videos recently. I have been working on projects and technical research, translating and writing articles to share with you.

All I want to say about this article is that everything that lets us write less code and keep it simple is a good thing!

This component, Dartx, may seem immature to some, but it represents an idea that you should use.

The original

Medium.com/flutter-com…

reference

  • Docs.microsoft.com/en-us/dotne…
  • Pub. Dev/packages/da…

The body of the

Darts Iterable and List provide a basic set of methods for modifying and querying collections. However, coming from the C # background, which has a remarkable library of LINQ-to-objects, I felt that part of my daily use was missing. Of course, any task can be solved using just the Dart.core method, but sometimes a multi-line solution is required, and the code is not so obvious that it takes effort to understand. As we all know, developers spend a lot of time reading code, and it’s critical to keep it simple.

The Dartx package allows developers to use elegant and readable single-line operations on collections (and other Dart types).

Pub. Dev/packages/da…

Here we compare how these tasks are solved:

  • first / last collection item or null / default value / by condition;
  • map / filter / iterate collection items depending on their index;
  • converting a collection to a map;
  • sorting collections;
  • collecting unique items;
  • min / max / average by items property;
  • filtering out null items;

Install dartxpubspec.yaml

dependencies:
  dartx: ^ 0.7.1
Copy the code
import 'package:dartx/dartx.dart';
Copy the code

First/last collection item…

… or null

To get a simple dart for the first and last collection items, you can write:

final first = list.first;
final last = list.last;
Copy the code

If list is empty, statereError is thrown, or null is explicitly returned:

final firstOrNull = list.isNotEmpty ? list.first : null;
final lastOrNull = list.isNotEmpty ? list.last : null;
Copy the code

Using DarTX you can:

final firstOrNull = list.firstOrNull;
final lastOrNull = list.lastOrNull;
Copy the code

In a similar way:

final elementAtOrNull = list.elementAtOrNull(index);
Copy the code

If the index exceeds the bounds of the list, null is returned.

… or default value

Given that you remember that now. The first and. When the list is empty, the Last getter throws an error to get the first and last collection items or default values. In simple Dart, you write:

final firstOrDefault = (list.isNotEmpty ? list.first : null)?? defaultValue;final lastOrDefault = (list.isNotEmpty ? list.last : null)?? defaultValue;Copy the code

Using DarTX you can:

final firstOrDefault = list.firstOrDefault(defaultValue);

final lastOrDefault = list.lastOrElse(defaultValue);
Copy the code

Similar to elementAtOrNull:

final elementAtOrDefault = list.elementAtOrDefault(index, defaultValue);
Copy the code

If the index exceeds the bounds of the list, defaultValue is returned.

… by condition

To get the first and last collection items that meet some criteria or NULL, a normal Dart implementation would be:

final firstWhere = list.firstWhere((x) => x.matches(condition));

final lastWhere = list.lastWhere((x) => x.matches(condition));
Copy the code

Unless orElse is provided, it will throw StateError for the empty list:

final firstWhereOrNull = list.firstWhere((x) => x.matches(condition), orElse: () => null);

final lastWhereOrNull = list.lastWhere((x) => x.matches(condition), orElse: () => null);
Copy the code

Using DarTX you can:

final firstWhereOrNull = list.firstOrNullWhere((x) => x.matches(condition));

final lastWhereOrNull = list.lastOrNullWhere((x) => x.matches(condition));
Copy the code

… collection items depending on their index

The Map…

This is not uncommon when you need to get a new collection in which each item depends on its index in some way. For example, each new item is a string representation of an item from the original collection and its index.

If you like one of my one-liners, the short answer is:

final newList = list.asMap()
  .map((index, x) => MapEntry(index, '$index $x'))
  .values
  .toList();
Copy the code

Using DarTX you can:

final newList = list.mapIndexed((index, x) => '$index $x').toList();
Copy the code

I apply.tolist () because this and most other extension methods return lazy Iterable.

Filter…

For another example, suppose you only need to collect odd index entries. With simple darts, this can be done:

final oddItems = [];
for (var i = 0; i < list.length; i++) {
  if(i.isOdd) { oddItems.add(list[i]); }}Copy the code

Or use a line of code:

final oddItems = list.asMap()
  .entries
  .where((entry) => entry.key.isOdd)
  .map((entry) => entry.value)
  .toList();
Copy the code

Using DarTX you can:

final oddItems = list.whereIndexed((x, index) => index.isOdd).toList();

// or

final oddItems = list.whereNotIndexed((x, index) => index.isEven).toList();
Copy the code

Iterate…

How do I record collection contents and specify item indexes?

In plain Dart:

for (var i = 0; i < list.length; i++) {
  print('$i: ${list[i]}');
}
Copy the code

Using DarTX you can:

list.forEachIndexed((element, index) => print('$index: $element'));
Copy the code

Converting a collection to a map

For example, you need to convert a list of different Person objects to Map < String, Person >, where the key is Person.id and the value is the full Person instance.

final peopleMap = people.asMap().map((index, person) => MapEntry(person.id, person));
Copy the code

Using DarTX you can:

final peopleMap = people.associate((person) => MapEntry(person.id, person));

// or

final peopleMap = people.associateBy((person) => person.id);
Copy the code

To get a Map where the key is DateTime and the value is a list of people born that day < person >, in simple Dart you can write:

final peopleMapByBirthDate = people.fold<Map<DateTime.List<Person>>>(
  <DateTime.List<Person>>{},
  (map, person) {
    if(! map.containsKey(person.birthDate)) { map[person.birthDate] = <Person>[]; } map[person.birthDate].add(person);returnmap; });Copy the code

Using DarTX you can:

final peopleMapByBirthDate = people.groupBy((person) => person.birthDate);
Copy the code

Sorting collections

How would you classify a collection with a regular DART? You must bear that in mind

list.sort();
Copy the code

Modify the source collection. To get a new instance, you must write:

final orderedList = [...list].sort();
Copy the code

Dartx provides an extension to get a new List instance:

final orderedList = list.sorted();

// and

final orderedDescendingList = list.sortedDescending();
Copy the code

How do I sort collection items based on certain attributes?

Plain Dart:

finalorderedPeople = [...people] .. sort((person1, person2) => person1.birthDate.compareTo(person2.birthDate));Copy the code

Using DarTX you can:

final orderedPeople = people.sortedBy((person) => person.birthDate);

// and

final orderedDescendingPeople = people.sortedByDescending((person) => person.birthDate);
Copy the code

Further, you can sort collection items by multiple attributes:

final orderedPeopleByAgeAndName = people
  .sortedBy((person) => person.birthDate)
  .thenBy((person) => person.name);

// and

final orderedDescendingPeopleByAgeAndName = people
  .sortedByDescending((person) => person.birthDate)
  .thenByDescending((person) => person.name);
Copy the code

Collecting unique items

To get different collection items, you can use the following simple Dart implementation:

final unique = list.toSet().toList();
Copy the code

This does not guarantee keeping projects in order or coming up with a multi-line solution

Using DarTX you can:

final unique = list.distinct().toList();

// and

final uniqueFirstNames = people.distinctBy((person) => person.firstName).toList();
Copy the code

Min / max / average by item property

For example, to find a min/ Max collection item, we can sort it and get the first/last item:

finalmin = ([...list].. sort()).first;finalmax = ([...list].. sort()).last;Copy the code

The same method applies to sorting by item attribute:

finalminAge = (people.map((person) => person.age).toList().. sort()).first;finalmaxAge = (people.map((person) => person.age).toList().. sort()).last;Copy the code

Or:

finalyoungestPerson = ([...people].. sort((person1, person2) => person1.age.compareTo(person2.age))).first;finaloldestPerson = ([...people].. sort((person1, person2) => person1.age.compareTo(person2.age))).last;Copy the code

Using DarTX you can:

final youngestPerson = people.minBy((person) => person.age);

final oldestPerson = people.maxBy((person) => person.age);
Copy the code

For empty collections, it returns NULL.

If a collection item implements Comparable, the method without a selector can be applied:

final min = list.min();

final max = list.max();
Copy the code

You can also easily get the average:

final average = list.average();

// and

final averageAge = people.averageBy((person) => person.age);
Copy the code

And the sum of the num set or num item attributes:

final sum = list.sum();

// and

final totalChildrenCount = people.sumBy((person) => person.childrenCount);
Copy the code

Filtering out null items

With plain Dart:

finalnonNullItems = list.where((x) => x ! =null).toList();
Copy the code

Using DarTX you can:

final nonNullItems = list.whereNotNull().toList();
Copy the code

More useful extensions

There are other useful extensions in DARTX. We won’t go into more details here, but I hope the naming and code are self-explanatory.

joinToString

final report = people.joinToString(
  separator: '\n',
  transform: (person) => '${person.firstName}_${person.lastName}',
  prefix: '< < ️',
  postfix: '> >',);Copy the code

all (every) / none

final allAreAdults = people.all((person) => person.age >= 18);

final allAreAdults = people.none((person) => person.age < 18);
Copy the code

first / second / third / fourth collection items

final first = list.first;
final second = list.second;
final third = list.third;
final fourth = list.fourth;
Copy the code

takeFirst / takeLast

final youngestPeople = people.sortedBy((person) => person.age).takeFirst(5);

final oldestPeople = people.sortedBy((person) => person.age).takeLast(5);
Copy the code

firstWhile / lastWhile

final orderedPeopleUnder50 = people
  .sortedBy((person) => person.age)
  .firstWhile((person) => person.age < 50)
  .toList();

final orderedPeopleOver50 = people
  .sortedBy((person) => person.age)
  .lastWhile((person) => person.age >= 50)
  .toList();
Copy the code

conclusion

The Dartx package includes many extensions for Iterable, List, and other Dart types. The best way to explore its capabilities is to browse the source code.

Github.com/leisim/dart…

Thanks to package authors Simon Leier and Pascal Welsch.

www.linkedin.com/in/simon-le…

twitter.com/passsy


The elder brother of the © cat

ducafecat.tech/

github.com/ducafecat

The issue of

Open source

GetX Quick Start

Github.com/ducafecat/g…

News client

Github.com/ducafecat/f…

Strapi manual translation

getstrapi.cn

Wechat discussion group Ducafecat

A series of collections

The translation

Ducafecat. Tech/categories /…

The open source project

Ducafecat. Tech/categories /…

Dart programming language basics

Space.bilibili.com/404904528/c…

Start Flutter with zero basics

Space.bilibili.com/404904528/c…

Flutter combat news client from scratch

Space.bilibili.com/404904528/c…

Flutter component development

Space.bilibili.com/404904528/c…

Flutter Bloc

Space.bilibili.com/404904528/c…

Flutter Getx4

Space.bilibili.com/404904528/c…

Docker Yapi

Space.bilibili.com/404904528/c…