This picture is a tribute to kallehallden, loves programming, keeps a curious heart
Old iron remember to forward, Brother Mao will present more Flutter good articles~~~~
WeChat flutter training group ducafecat
Brother Cat said
Recently, I have no time to record videos. I have been doing project and technical research, and I just translated and wrote articles to share with you.
Regarding this article, I just want to say that everything that allows us to write less code and keep the code concise is a good thing!
Maybe this component dartx is not mature enough in the eyes of some people, but this represents an idea that you should learn from.
original
https://medium.com/flutter-community/dart-collections-with-dartx-extensions-959a0b42849e
reference
- https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/concepts/linq/linq-to-objects
- https://pub.dev/packages/dartx
text
Darts Iterable and List provide a set of basic methods to modify and query collections. However, coming from the c# background, it has an extraordinary LINQ-to-Objects library, and I feel that part of my daily use is missing. Of course, any task can be solved using only the dart.core method, but sometimes a multi-line solution is required, and the code is not so obvious and requires effort to understand. We all know that developers spend a lot of time reading code and it is vital that the code is concise and clear.
The Dartx package allows developers to use elegant and readable one-line operations on collections (and other Dart types).
https://pub.dev/packages/dartx
Below we will 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 dartx pubspec.yaml
dependencies:
dartx: ^0.7.1
import 'package:dartx/dartx.dart';
First / last collection item…
… or null
In order to get a simple provincial road for the first and last collection items, you can write like this:
final first = list.first;
final last = list.last;
If the list is empty, statereerror is thrown, or null is returned explicitly:
final firstOrNull = list.isNotEmpty ? list.first : null;
final lastOrNull = list.isNotEmpty ? list.last : null;
Use dartx to:
final firstOrNull = list.firstOrNull;
final lastOrNull = list.lastOrNull;
Similarly:
final elementAtOrNull = list.elementAtOrNull(index);
If the index exceeds the limit of the list, null is returned.
… or default value
Given that you remember this now. First sum. When the list is empty, the last getter will throw an error to get the first and last collection items or default values. In simple Dart, you would write:
final firstOrDefault = (list.isNotEmpty ? list.first : null) ?? defaultValue;
final lastOrDefault = (list.isNotEmpty ? list.last : null) ?? defaultValue;
Use dartx to:
final firstOrDefault = list.firstOrDefault(defaultValue);
final lastOrDefault = list.lastOrElse(defaultValue);
Similar to elementAtOrNull:
final elementAtOrDefault = list.elementAtOrDefault(index, defaultValue);
If the index exceeds the boundary of the list, the defaultValue is returned.
… by condition
To get the first and last collection items that meet certain conditions or null, a common Dart implementation should be:
final firstWhere = list.firstWhere((x) => x.matches(condition));
final lastWhere = list.lastWhere((x) => x.matches(condition));
Unless orElse is provided, it will throw a StateError for an empty list:
final firstWhereOrNull = list.firstWhere((x) => x.matches(condition), orElse: () => null);
final lastWhereOrNull = list.lastWhere((x) => x.matches(condition), orElse: () => null);
Use dartx to:
final firstWhereOrNull = list.firstOrNullWhere((x) => x.matches(condition));
final lastWhereOrNull = list.lastOrNullWhere((x) => x.matches(condition));
… collection items depending on their index
Map…
This is not uncommon when you need to obtain a new collection where each item depends on its index in some way. For example, each new item is a string representation of the item and its index from the original collection.
If you like one of my quips, it simply is:
final newList = list.asMap()
.map((index, x) => MapEntry(index, '$index $x'))
.values
.toList();
Use dartx to:
final newList = list.mapIndexed((index, x) => '$index $x').toList();
I applied .toList() because this and most other extension methods return lazy Iterable.
Filter...
For another example, suppose that only odd index entries need to be collected. Use simple province roads, can be achieved like this:
final oddItems = [];
for (var i = 0; i < list.length; i++) {
if (i.isOdd) {
oddItems.add(list[i]);
}
}
Or with one line of code:
final oddItems = list.asMap()
.entries
.where((entry) => entry.key.isOdd)
.map((entry) => entry.value)
.toList();
Use dartx to:
final oddItems = list.whereIndexed((x, index) => index.isOdd).toList();
// or
final oddItems = list.whereNotIndexed((x, index) => index.isEven).toList();
Iterate…
How to record the contents of the collection and specify the item index?
In plain Dart:
for (var i = 0; i < list.length; i++) {
print('$i: ${list[i]}');
}
Use dartx to:
list.forEachIndexed((element, index) => print('$index: $element'));
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 complete Person instance.
final peopleMap = people.asMap().map((index, person) => MapEntry(person.id, person));
Use dartx to:
final peopleMap = people.associate((person) => MapEntry(person.id, person));
// or
final peopleMap = people.associateBy((person) => person.id);
To get a Map, where the key is DateTime and the value is a list of people who were 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);
return map;
},
);
Use dartx to:
final peopleMapByBirthDate = people.groupBy((person) => person.birthDate);
Sorting collections
How would you sort a collection with ordinary dart? You have to keep this in mind
list.sort();
To modify the source collection, to get a new instance, you must write:
final orderedList = [...list].sort();
Dartx provides an extension to obtain a new List instance:
final orderedList = list.sorted();
// and
final orderedDescendingList = list.sortedDescending();
How to sort the collection items based on certain attributes?
Plain Dart:
final orderedPeople = [...people]
..sort((person1, person2) => person1.birthDate.compareTo(person2.birthDate));
Use dartx to:
final orderedPeople = people.sortedBy((person) => person.birthDate);
// and
final orderedDescendingPeople = people.sortedByDescending((person) => person.birthDate);
Furthermore, you can sort the 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);
Collecting unique items
To get different collection items, you can use the following simple Dart implementation:
final unique = list.toSet().toList();
This does not guarantee to maintain the order of items or propose a multi-line solution
Use dartx to:
final unique = list.distinct().toList();
// and
final uniqueFirstNames = people.distinctBy((person) => person.firstName).toList();
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:
final min = ([...list]..sort()).first;
final max = ([...list]..sort()).last;
The same method applies to sorting by item attributes:
final minAge = (people.map((person) => person.age).toList()..sort()).first;
final maxAge = (people.map((person) => person.age).toList()..sort()).last;
or:
final youngestPerson =
([...people]..sort((person1, person2) => person1.age.compareTo(person2.age))).first;
final oldestPerson =
([...people]..sort((person1, person2) => person1.age.compareTo(person2.age))).last;
Use dartx to:
final youngestPerson = people.minBy((person) => person.age);
final oldestPerson = people.maxBy((person) => person.age);
For an empty collection, it will return null.
If the collection item implements Comparable, you can apply the method without a selector:
final min = list.min();
final max = list.max();
You can also get the average easily:
final average = list.average();
// and
final averageAge = people.averageBy((person) => person.age);
And the sum of num collection or num item attributes:
final sum = list.sum();
// and
final totalChildrenCount = people.sumBy((person) => person.childrenCount);
Filtering out null items
With plain Dart:
final nonNullItems = list.where((x) => x != null).toList();
Use dartx to:
final nonNullItems = list.whereNotNull().toList();
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: '>>',
);
all (every) / none
final allAreAdults = people.all((person) => person.age >= 18);
final allAreAdults = people.none((person) => person.age < 18);
first / second / third / fourth collection items
final first = list.first;
final second = list.second;
final third = list.third;
final fourth = list.fourth;
takeFirst / takeLast
final youngestPeople = people.sortedBy((person) => person.age).takeFirst(5);
final oldestPeople = people.sortedBy((person) => person.age).takeLast(5);
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();
to sum up
The Dartx package contains many extensions for Iterable, List and other Dart types. The best way to explore its functionality is to browse the source code.
https://github.com/leisim/dartx
Thanks to the package authors Simon Leier and Pascal Welsch.
https://www.linkedin.com/in/simon-leier/
© Cat brother
Past
Open source
GetX Quick Start
https://github.com/ducafecat/getx_quick_start
News client
https://github.com/ducafecat/flutter_learn_news
strapi manual translation
WeChat discussion group ducafecat
Series collection
Translation
https://ducafecat.tech/categories/%E8%AF%91%E6%96%87/
Open source project
https://ducafecat.tech/categories/%E5%BC%80%E6%BA%90/
Dart programming language basics
https://space.bilibili.com/404904528/channel/detail?cid=111585
Getting started with Flutter zero foundation
https://space.bilibili.com/404904528/channel/detail?cid=123470
Flutter actual combat from scratch news client
https://space.bilibili.com/404904528/channel/detail?cid=106755
Flutter component development
https://space.bilibili.com/404904528/channel/detail?cid=144262
Flutter Bloc
https://space.bilibili.com/404904528/channel/detail?cid=177519
Flutter Getx4
https://space.bilibili.com/404904528/channel/detail?cid=177514
Docker Yapi
https://space.bilibili.com/404904528/channel/detail?cid=130578
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。