Lists in Dart
are handy. It is the most used data structure and can be used in many different ways to model and solve a whole bunch of problems. The lists are SO awesome. In this article, we’ll look at some tips and tricks when working with Kotlin lists.
Most of these tricks “I mostly used in my day-to-day development and I hope you’ll find them useful too.”
Show me the code.
final list = [‘Ahsen’ , ‘Saeed’ , ‘Just’ , ‘Another’ , ‘Programming Nerd’ , ‘Ahsen’); final foldedList = list.fold({}, (acc, curr) { acc[curr] = (acc[curr] ?? 0) + 1; return acc; }) as Map<dynamic, dynamic>; // sort the keys to get the maximum value inside the map final sortedKeys = foldedList.keys.toList() ..sort((a, b) => foldedList[b].compareTo(folded[a])); print(‘Occurence maximum time --> ${sortedKeys.first}’);
void main() { final words = ['Hello', 'world', 'from', 'Dart']; String result = words.join(' '); // Join elements with a space in between print(result); // Output: Hello world from Dart }
The above join
creates a string from all the elements separated using the separator which is white space in the above example. You can pass any string separator you want.
void main() { var listA = <int>[1, 2, 3]; var listB = <int>[4, 5, 6]; // Swapping using list destructuring [listA, listB] = [listB, listA]; print('\nAfter swapping:'); print('List A: $listA'); print('List B: $listB'); }
I know, I know you may think What the heck is this :sweat_smile: . Let me explain it to you, We update the lists by creating new lists using the spread operator and setting the list1
to a new list containing all the elements of list2
. Then, we set list2
to a new list containing all the elements of the newly updated list1
.
final avengerNames = [‘Chris Evans’, ‘Jeremy Renner’, ‘Scarlett Johansson’, ‘Josh Brolin’, ‘Chris Hemsworth’]; final numbers = [5, 8, 1, 6, 10, 4, 7, 3, 9, 2]; void main() { avengerNames.sort(); print(‘Avengers names in ascending -> $avengerNames’); avengerNames.sort((a, b) => b.compareTo(a)); print(‘Avengers names in descending $avengerNames’); numbers.sort(); print(‘Numbers in ascending -> $numbers’); numbers.sort((a, b) => b.compareTo(a)); print(‘Numbers in descending -> $numbers’); } // output of the above code Avengers names in ascending -> [Chris Evans, Chris Hemsworth, Jeremy Renner, Josh Brolin, Scarlett Johansson] Avengers names in descending [Scarlett Johansson, Josh Brolin, Jeremy Renner, Chris Hemsworth, Chris Evans] Numbers in ascending -> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] Numbers in descending -> [10, 9, 8, 7, 6, 5, 4, 3, 2, 1]
The default behavior of the sort
function is to use natural ordering for the elements and if you want to sort the list in descending order, you can pass a custom comparator function (a, b) => b.compareTo(a)
compares two strings in reverse order, resulting in a descending sort.
final numbers = [5, 8, 1, 6, 10, 10, 7, 10, 9, 10]; void main() { final distinctList = numbers.toSet(); print(‘Distinct numbers -> $distinctList’); } // output of the above code Distinct numbers -> {5, 8, 1, 6, 10, 7, 9}
OK OK 😛, I know what you guys must be thinking this is the easiest example you have chosen. Now, let’s say we have this collection of users and we want to remove the duplicates from it.
class User { final String id; final String name; User(this.id, this.name); @override bool operator ==(Object other) => identical(this, other) || other is User && runtimeType == other.runtimeType && id == other.id && name == other.name; @override int get hashCode => id.hashCode ^ name.hashCode; } void main() { List<User> users = [User(‘1’, ‘Alice’), User(‘2’, ‘Bob’), User(‘1’, ‘Alice’), User(‘4’, ‘David’), User(‘2’, ‘Bob’)]; Set<User> distinctUsers = users.toSet(); for (final user in distinctUsers) { print(‘ID: ${user.id}, Name: ${user.name}’); } }
final animals = [‘Baboon’, ‘Argalis’, ‘Cat’, ‘Lion’, ‘Monkey’, ‘Zebra’, ‘Fox’, ‘Elephant’]; final numbers = [10, 2, 3, 4, 5, 1, 2, 3, 6, 7, 5, 9]; void main() { int minNumber = numbers.reduce((min, element) => element < min ? element : min); int maxNumber = numbers.reduce((max, element) => element > max ? element : max); String minAnimal = animals.reduce((minWord, word) => word.length < minWord.length ? word : minWord); String maxAnimal = animals.reduce((maxWord, word) => word.compareTo(maxWord) > 0 ? word : maxWord); print(‘Min animal: $minAnimal, min number: $minNumber, max number: $maxNumber, and max animal: $maxAnimal’); } /// Output of the above program Min animal: Cat, min number: 1, max number: 10, and max animal: Zebra
To find the minimum element in a collection of strings in dart
, you can use the reduce
method or loop through the collection while keeping track of the minimum value on the other hand for the maximum element we can also use the reduce
method through out the collection while keeping track of the maximum value.
final numbers = [1, 2, 3, 4, 5]; void main() { final productResult = numbers.reduce((value, element) => value + element); print(productResult); }
The reduce
method is a little complicated so I am trying to explain its inner workings. Initially, the reduce
method calls out the first two items from a list and returns the result. The function is then called again with the result obtained previously and the next value in the list. This process keeps repeating until there are items on the list.
You can check out this question on Stack Overflow difference between the reduce
and fold
methods.
final avengers = [‘Chris Evans’, ‘Jeremy Renner’, ‘Scarlett Johansson’, ‘Josh Brolin’, ‘Chris Hemsworth’]; void main() { final reversedAvengers = avengers.reversed; print(reversedAvengers); } /// Output of the above program (Chris Hemsworth, Josh Brolin, Scarlett Johansson, Jeremy Renner, Chris Evans)
The reversed
property returns an iterable
that provides elements in reverse order. You can convert this iterable back to a list using the toList()
method.
Map<T, List<S>> groupBy<S, T>(Iterable<S> values, T Function(S) key) { var map = <T, List<S>>{}; for (var element in values) { (map[key(element)] ??= []).add(element); } return map; }
Above we write the generic groupBy
function which we can use on any type of Iterable.
class Person { final String name; final int age; const Person(this.name, this.age); } const persons = [ Person(‘Alice’, 25), Person(‘Bob’, 30), Person(‘Carol’, 25), Person(‘David’, 35), Person(‘Eve’, 30) ]; void main() { final personsGroupBy = groupBy(persons, (person) => person.age); print(personsGroupBy); } /// Output of the above program. {25: [Instance of ‘Person’, Instance of ‘Person’], 30: [Instance of ‘Person’, Instance of ‘Person’], 35: [Instance of ‘Person’]}
In this above example, the groupBy
function is used to group Person objects by their age. The resulting personsGroupBy
map will have age as the key and a list of Person objects with the same age as the value.
This can be particularly useful when you want to group elements from a list based on a certain property or criteria.
const animals = [‘Baboon’, ‘Argalis’, ‘Cat’, ‘Lion’, ‘Monkey’, ‘Zebra’, ‘Fox’, ‘Elephant’]; void main() { final shuffledAnimals = [...animals]..shuffle(); print(shuffledAnimals); } /// Output of above program [Zebra, Fox, Cat, Baboon, Monkey, Lion, Elephant, Argalis]
In the symphony of programming, dart collections play a harmonious role, orchestrating data with finesse and efficiency. As you journey through the art of coding, remember that the right collection can transform a mere sequence of characters into a composition of elegance and clarity. With each array, set, and map, you’re not just crafting code; you’re creating a masterpiece. If you think I should add more or have any suggestion please do comment below. I’ll keep updating this article. Also, if you like this post don’t forget to share it. Thanks for being here and keep reading…
That’s all for now. Thank you for reading.
Quick Links
Legal Stuff