本次圖片是向 kallehallden 致敬,熱愛編程,保持一顆好奇的心
最近沒時間錄視頻,一直在作項目和技術研究,就翻譯和寫寫文章和你們分享。git
關於這篇文章,我只想說一切讓咱們少寫代碼,讓代碼簡潔的方式都是好東西!github
也許這個組件 dartx 在某些人眼裏不夠成熟,可是這表明了一種思路,你應該去借鑑。編程
https://medium.com/flutter-co...
Darts Iterable 和 List 提供了一組基本的方法來修改和查詢集合。然而,來自 c # 背景,它有一個非凡的 LINQ-to-Objects 庫,我以爲我平常使用的一部分功能缺失了。固然,任何任務均可以只使用 dart.core 方法來解決,但有時須要多行解決方案,並且代碼不是那麼明顯,須要花費精力去理解。咱們都知道,開發人員花費大量時間閱讀代碼,使代碼簡潔明瞭是相當重要的。api
Dartx 包容許開發人員在集合(和其餘 Dart 類型)上使用優雅且可讀的單行操做。微信
https://pub.dev/packages/dartx編程語言
下面咱們將比較這些任務是如何解決的:ide
pubspec.yaml
dependencies: dartx: ^0.7.1
import 'package:dartx/dartx.dart';
爲了獲得第一個和最後一個收集項目的簡單省道,你能夠這樣寫:post
final first = list.first; final last = list.last;
若是 list 爲空,則拋出 statereerror,或者顯式返回 null:ui
final firstOrNull = list.isNotEmpty ? list.first : null; final lastOrNull = list.isNotEmpty ? list.last : null;
使用 dartx 能夠:spa
final firstOrNull = list.firstOrNull; final lastOrNull = list.lastOrNull;
相似地:
final elementAtOrNull = list.elementAtOrNull(index);
若是索引超出列表的界限,則返回 null。
鑑於你如今記住這一點。第一和。當 list 爲空時,last getter 會拋出錯誤,以獲取第一個和最後一個集合項或默認值,在簡單的 Dart 中,你會寫:
final firstOrDefault = (list.isNotEmpty ? list.first : null) ?? defaultValue; final lastOrDefault = (list.isNotEmpty ? list.last : null) ?? defaultValue;
使用 dartx 能夠:
final firstOrDefault = list.firstOrDefault(defaultValue); final lastOrDefault = list.lastOrElse(defaultValue);
相似於 elementAtOrNull:
final elementAtOrDefault = list.elementAtOrDefault(index, defaultValue);
若是索引超出列表的邊界,則返回 defaultValue。
要獲取第一個和最後一個符合某些條件或 null 的集合項,一個普通的 Dart 實現應該是:
final firstWhere = list.firstWhere((x) => x.matches(condition)); final lastWhere = list.lastWhere((x) => x.matches(condition));
除非提供 orElse,不然它將爲空列表拋出 StateError:
final firstWhereOrNull = list.firstWhere((x) => x.matches(condition), orElse: () => null); final lastWhereOrNull = list.lastWhere((x) => x.matches(condition), orElse: () => null);
使用 dartx 能夠:
final firstWhereOrNull = list.firstOrNullWhere((x) => x.matches(condition)); final lastWhereOrNull = list.lastOrNullWhere((x) => x.matches(condition));
當您須要得到一個新的集合,其中每一個項目以某種方式依賴於其索引時,這種狀況並不罕見。例如,每一個新項都是來自原始集合的項及其索引的字符串表示形式。
若是你喜歡個人一句俏皮話,簡單地說就是:
final newList = list.asMap() .map((index, x) => MapEntry(index, '$index $x')) .values .toList();
使用 dartx 能夠:
final newList = list.mapIndexed((index, x) => '$index $x').toList();
我應用.toList ()是由於這個和大多數其餘擴展方法返回 lazy Iterable。
對於另外一個示例,假設只須要收集奇數索引項。使用簡單省道,能夠這樣實現:
final oddItems = []; for (var i = 0; i < list.length; i++) { if (i.isOdd) { oddItems.add(list[i]); } }
或者用一行代碼:
final oddItems = list.asMap() .entries .where((entry) => entry.key.isOdd) .map((entry) => entry.value) .toList();
使用 dartx 能夠:
final oddItems = list.whereIndexed((x, index) => index.isOdd).toList(); // or final oddItems = list.whereNotIndexed((x, index) => index.isEven).toList();
如何記錄集合內容並指定項目索引?
In plain Dart:
for (var i = 0; i < list.length; i++) { print('$i: ${list[i]}'); }
使用 dartx 能夠:
list.forEachIndexed((element, index) => print('$index: $element'));
例如,須要將不一樣 Person 對象的列表轉換爲 Map < String,Person > ,其中鍵是 Person.id,值是完整 Person 實例。
final peopleMap = people.asMap().map((index, person) => MapEntry(person.id, person));
使用 dartx 能夠:
final peopleMap = people.associate((person) => MapEntry(person.id, person)); // or final peopleMap = people.associateBy((person) => person.id);
要獲得一個 Map,其中鍵是 DateTime,值是列出那天出生的人的名單 < person > ,在簡單的 Dart 中,你能夠寫:
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; }, );
使用 dartx 能夠:
final peopleMapByBirthDate = people.groupBy((person) => person.birthDate);
你會怎樣用普通的 dart 來分類一個收集? 你必須記住這一點
list.sort();
修改源集合,要獲得一個新實例,你必須寫:
final orderedList = [...list].sort();
Dartx 提供了一個擴展來得到一個新的 List 實例:
final orderedList = list.sorted(); // and final orderedDescendingList = list.sortedDescending();
如何基於某些屬性對收集項進行排序?
Plain Dart:
final orderedPeople = [...people] ..sort((person1, person2) => person1.birthDate.compareTo(person2.birthDate));
使用 dartx 能夠:
final orderedPeople = people.sortedBy((person) => person.birthDate); // and final orderedDescendingPeople = people.sortedByDescending((person) => person.birthDate);
更進一步,你能夠經過多個屬性對集合項進行排序:
final orderedPeopleByAgeAndName = people .sortedBy((person) => person.birthDate) .thenBy((person) => person.name); // and final orderedDescendingPeopleByAgeAndName = people .sortedByDescending((person) => person.birthDate) .thenByDescending((person) => person.name);
要得到不一樣的集合項,可使用如下簡單的 Dart 實現:
final unique = list.toSet().toList();
這並不保證保持項目順序或提出一個多行的解決方案
使用 dartx 能夠:
final unique = list.distinct().toList(); // and final uniqueFirstNames = people.distinctBy((person) => person.firstName).toList();
例如,要查找一個 min/max 集合項,咱們能夠對其進行排序,並獲取 first/last 項:
final min = ([...list]..sort()).first; final max = ([...list]..sort()).last;
一樣的方法也適用於按項屬性進行排序:
final minAge = (people.map((person) => person.age).toList()..sort()).first; final maxAge = (people.map((person) => person.age).toList()..sort()).last;
或:
final youngestPerson = ([...people]..sort((person1, person2) => person1.age.compareTo(person2.age))).first; final oldestPerson = ([...people]..sort((person1, person2) => person1.age.compareTo(person2.age))).last;
使用 dartx 能夠:
final youngestPerson = people.minBy((person) => person.age); final oldestPerson = people.maxBy((person) => person.age);
對於空集合,它將返回 null。
若是收集項目實現了 Comparable,則能夠應用不帶選擇器的方法:
final min = list.min(); final max = list.max();
你也能夠很容易地獲得平均值:
final average = list.average(); // and final averageAge = people.averageBy((person) => person.age);
以及 num 集合或 num 項屬性的總和:
final sum = list.sum(); // and final totalChildrenCount = people.sumBy((person) => person.childrenCount);
With plain Dart:
final nonNullItems = list.where((x) => x != null).toList();
使用 dartx 能夠:
final nonNullItems = list.whereNotNull().toList();
在 dartx 中還有其餘有用的擴展。這裏咱們不會深刻討論更多細節,可是我但願命名和代碼是不言自明的。
final report = people.joinToString( separator: '\n', transform: (person) => '${person.firstName}_${person.lastName}', prefix: '<<️', postfix: '>>', );
final allAreAdults = people.all((person) => person.age >= 18); final allAreAdults = people.none((person) => person.age < 18);
final first = list.first; final second = list.second; final third = list.third; final fourth = list.fourth;
final youngestPeople = people.sortedBy((person) => person.age).takeFirst(5); final oldestPeople = people.sortedBy((person) => person.age).takeLast(5);
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();
Dartx 包包含了許多針對 Iterable、 List 和其餘 Dart 類型的擴展。探索其功能的最佳方式是瀏覽源代碼。
https://github.com/leisim/dartx
感謝軟件包做者 Simon Leier 和 Pascal Welsch。
https://www.linkedin.com/in/s...
© 貓哥
https://github.com/ducafecat/...
https://github.com/ducafecat/...
https://ducafecat.tech/catego...
https://ducafecat.tech/catego...
https://space.bilibili.com/40...
https://space.bilibili.com/40...
https://space.bilibili.com/40...
https://space.bilibili.com/40...
https://space.bilibili.com/40...
https://space.bilibili.com/40...