{"componentChunkName":"component---src-templates-lesson-post-js","path":"/lesson/looping-for-in-and-for-each","result":{"data":{"strapiLesson":{"id":"Lesson_52","author":{"email":"eric@ericwindmill.com","username":"Eric Windmill","twitter":"ericwindmill"},"content":"<div class='aside'>\nFor most of the remainder of the section, I'll be using `List`, as its the most common iterable, but most of the knowledge could be applied to all iterables, including `Set`. \n</div>\n\nLists (and iterables and sets) are the primary objects that you'll _loop_ over. You can see basic examples of `for`, `while` and `do-while` loops in the Loops lesson in the Control Flow section. Here, let's take a deeper look at two other looping mechanisms: `for-in` loops and the `forEach` method on iterables.\n\nBoth are used for the same purpose: performing an action on _each_ element in the list. Importantly, both are used primarily for _side effects_. The original list will not be changed, nor will you be returned any new value from these methods.  \n\n### for-in loops\n\nFor-in loops function similarly to standard `for` loops, but there are two differences: \n    1. It easier to write. \n    2. You won't have access, by default, to the index of the element in the list.\n\nFor-in loops are preferable to for loops to me, because they are cleaner, but they don't really solve any problem that standard for loops wont.\n\nThis example shows the syntax for for-in loops, but as you can see there is no built-in way to get the index of the element in the list. It\n\n<pre>\n    <code class=\"language-run-dartpad:theme-light:mode-dart:split-60:width-100%:height-400px\">\nvoid main() {\n   List<int> ages = [29, 27, 42];\n   for (var age in ages) {\n     print(age);\n  }\n}\n</code></pre>\n\n### forEach\n\n`List.forEach` is a looping mechanism that is more difficult to grasp (if you aren't familiar with call backs), and provides very little benefit over using a for-loop.\n\nIt's best to just look at some code:\n\n<pre>\n    <code class=\"language-run-dartpad:theme-light:mode-dart:split-60:width-100%:height-600px\">\nvoid main() {\n   List<int> ages = [29, 27, 42];\n    // the arguement that forEach expects is \n    // a *call back*. This function will be called on\n    // each element\n   ages.forEach((int age) => print(age));\n}\n</code></pre>\n\nThat looks a bit more complex, but does the _exact_ same thing as the first example using `for-in` loop. In fact, look at this example comparing the two.\n\n\n<pre>\n    <code class=\"language-run-dartpad:theme-light:mode-dart:split-60:width-100%:height-600px\">\nvoid main() {\n   List<int> ages = [29, 27, 42];\n    \n    // should print 30, 28, 43\n    for (var age in ages) {\n        _addAndPrint(age);\n    }\n\n    // should print 30, 28, 43\n    ages.forEach((int age) => _addAndPrint(age));\n}\n\nvoid _addAndPrint(int number) {\n    print(1 + number);\n}\n</code></pre>\n\nWhile for-each is more complex to write, it's often favored because of how terse the code looks. For our purposed, it's important because many of the future methods we'll explore on lists and iterables follows this same pattern. \n\n<div class='aside'>\nThese methods that operate on collections are often called _functional_ methods in JavaScript, Dart, and beyond. If you hear someone talking about _functional_ programming in JS, they're likely talking about these specific methods, and not about pure functional programming. These methods are like a piece of functional programming languages that's been borrowed by languages that aren't necessarily functional.\nIn any case, they're used _a lot_ in UI development, so it's good to know them. \n</div>\n\n### Try it yourself: looping\n\n<iframe style=\"height:400px;width:100%;\" src=\"https://dartpad.dev/embed-inline.html?id=510e84f2bf31e395073aff739046d02f&split=60&theme=dark\"></iframe>\n\n\n","updated_at":"Monday, 20th of July, 2020","slug":"looping-for-in-and-for-each","strapiId":52,"title":"Looping: for-in and forEach","tutorial":{"category":"Dart","title":"Iterables, Iterators, and Collections"}},"strapiTutorial":{"lessons":[{"author":1,"content":"Adding elements to _lists_ is done with four elements. Importantly, this doesn't apply to the `Iterable` super class. These methods exist across different collections, such as `List` and `Set`, but not all methods exist on all collections.\n\n1. `add(element)` (list, set)\n    - adds one element, passed in as an argument, to the _end_ of a list.\n2. `addAll([element1, element2, etc])` (list, set, map)\n    - adds all the elements of one list to the end of the target list, maintaining ordering\n3. `insert(index, element)` (list)\n    - adds one element to the list at the given index, and then moves every element over 1 to make room\n4. `insertAll(index, [element1, element2, etc])` (list)\n    - adds all elements passed in as a list to the target list beginning at the index provided, and shifting the rest of the elements over.\n\nThese methods exist only on certain collections for good reason, which I'll discuss after we look at some examples of using these methods with a list.\n\n<pre>\n    <code class=\"language-run-dartpad:theme-light:mode-dart:split-60:width-100%:height-500px\">\nList<String> cities = ['Portland', 'Medellin', 'Tokyo'];\nvoid main() {\n    print(cities);\n    cities.add('Budapest');\n    print(cities);\n    cities.addAll(['Louisville', 'Bangkok']);\n    print(cities);\n    cities.insert(1, 'Chaing Mai');\n    print(cities[1]);\n    cities.insertAll(0, ['Paris', 'Baghdad', 'New York']);\n    print(cities);\n}\n</code></pre>\n\nTo determine if (or why) certain methods live on certain collections and not others, consider how these objects work. A `Map` has no use for a method like `insert` or `insertAll`, because it doesn't maintain or care about order. Similarly, not all `Set` implementations care about order. \n\nThese methods of course have an infinite number of use-cases. But one that's easy to show is using a list to represent a queue. A queue is an abstract data type that has one main rule: first-in-first-out. In human words, that means that the only element that can be removed from a queue is the element that was inserted first. Queue's can be nicely visualized like this:\n\n<img src=\"https://res.cloudinary.com/duqbhmg9i/image/upload/c_scale,h_525/v1589125921/flutter_by_example/queue_drawing_dcd5oq.png\" alt=\"queue drawing\">\n\nBecause of this, a queue needs to be able to insert elements at one end, and remove from the other end. This sort of fine control over the order of a list makes `insert` quite useful. \n\n#### Try it yourself, make a queue\n\n<iframe style=\"height:400px;width:100%;\" src=\"https://dartpad.dev/embed-inline.html?id=befbabc698e2ddff75a063efebe68e23&split=60&theme=dark\"></iframe>\n","created_at":"2020-07-19T19:35:01.012Z","id":54,"slug":"adding-elements-add-and-insert-all","title":"Adding elements: add and insert (all)","tutorial":6,"updated_at":"2020-07-20T15:25:00.824Z"},{"author":1,"content":"`fold`, `reduce` and `join` are some of the methods on iterables and lists that are used to generate a single value by combining on the elements of the list.\n\n`fold` and `reduce` are similar. They both iterate over the elements and perform an operation on each element _and_ the element created thus far in the iteration. That's a wonky statement, so consider `reduce` first with this example:\n\n```dart\n  List<int> nums = [1, 2, 3, 4, 5];\n  final sum = nums.reduce((int sumSoFar, int currentInt) {\n    return sumSoFar + currentInt;\n  });\n```\n\nThis example will add each number from the list together. Based on the variable names, perhaps you can see that at each iteration you have access to the _reduced value_ (in this case the sum), so far, as well as the current element that is going to be added to the `sumSoFar`.\n\nRunning this in DartPad with print statements might help:\n\n<pre>\n    <code class=\"language-run-dartpad:theme-light:mode-dart:split-60:width-100%:height-500px\">\nvoid main() {\n  List<int> nums = [1, 2, 3, 4, 5];\n  final sum = nums.reduce((int sumSoFar, int currentElement) {\n    print(\"sumSoFar $sumSoFar\");\n    print(\"currentElement $currentElement\");\n    print('--');\n    return sumSoFar + currentElement;\n  });\n  print(\"final sum == $sum\");\n}\n</code></pre>\n\nAs I mentioned, `fold` is quite similar to this. Before we look at fold, let's talk about the difference. `reduce` must return, from each iteration of the callback being called, the same type as the type of the elements of the list. for example:\n\n`<int>[1,2,3].reduce(callback)` must return an int from each call to teh callback.\n`<String>[\"hello\",\"world\"].reduce(callback)` must return an `String` from each call to teh callback.\n\nwhich means, this will throw an error:\n\n```dart\nvoid main() {\n  List<int> nums = [1, 2, 3, 4, 5];\n  final join = nums.reduce((int sumSoFar, int currentElement) {\n      return \"$sumSoFar$currentElement\"; // error! must return an int          \n  });\n}\n```\n \n#### fold\n\n`fold` is essentially the solution to the issue above. You can derive values of different types from `fold`, but it behaves much in the same way that `reduce` does.\n\nThe API difference is in what values are passed to `fold`, and the callback passed to `fold`. `fold` needs a \"starting value\", which it uses in the first iteration of the callback.\n\n<pre>\n    <code class=\"language-run-dartpad:theme-light:mode-dart:split-60:width-100%:height-500px\">\nvoid main() {\n  List<int> nums = [1, 2, 3, 4, 5];\n  // the starting value is an empty string.\n  // the values passed in are the derived value so far, as well as the current element.           \n  final join = nums.fold(\"\", (String stringSoFar, int currentElement) {\n      return \"$sumSoFar$currentElement\";\n  });\n}\n</code></pre>\n \n`fold` is another method that I find myself using quite often in the day to day.\n\n\n### Give it a whirl: derive a new value from a list\n\n<iframe style=\"height:400px;width:100%;\" src=\"https://dartpad.dev/embed-inline.html?id=1bfc7ca4f97d2bce611f1bd612b8a456&split=60&theme=dark\"></iframe>\n","created_at":"2020-07-19T19:45:42.646Z","id":59,"slug":"deriving-values-from-elements-fold-reduce-join","title":"Deriving values from elements: fold, reduce, join","tutorial":6,"updated_at":"2020-07-20T15:25:00.824Z"},{"author":1,"content":"\n<div class='disclaimer'>\nThis section is heavily inspired by Dart's own <a href=\"https://dart.dev/codelabs/iterables\">codelab</a> on the subject, it's less detailed (for beginners), but includes more methods and examples (for those looking for specific information, like <a href=\"https://api.dart.dev/stable/2.8.1/dart-core/Iterable/fold.html\">Iterable.fold</a>).\n</div>\n\nCollections are Dart objects that contain more objects, referred to as _elements_. For example a `Map` or `List`. An _iterable_ collection is a collection that implements the Dart class `Iterable`. The most common iterables are `List` and `Set`. \n\n<div class='aside'>\nA `Map` object is a collection, but not an iterable. Maps are covered in the latter part of this section, as it's often useful to _iterate_ over map properties as well. \n</div>\n\nIn a nutshell, an _iterable_ is a collection that _sequential_ access to its elements. In plain English, an iterable stores its elements in order, and you can find the elements within the collection by its position.\n\nIn code, that looks something like this:\n\n```dart\nIterable<String> greeting = ['Hello', 'World'];\n``` \n\n### Bracket Notation\n\nUsing the _bracket notation_ is the just the basic way to interact with iterables.\n \n<pre>\n    <code class=\"language-run-dartpad:theme-light:mode-dart:split-60:width-100%:height-600px\">\nIterable<String> greeting = ['Hello', 'World']; \nvoid main() {\n    var hello = greeting[0];\n    var world = greeting[1];\n\n    print(hello);\n    print(world);\n}\n</code>\n</pre>\n\nLike in most languages, Dart's iterables are 0-indexed, and you can access te different elements by their index. \n\nAlong with indexing, there are a variety of methods and properties on iterables that are handy, and we'll explore throughout this section.\n\n<div class='aside'>\nFor most of the remainder of the section, I'll be using `List`, as its the most common iterable, but most of the knowledge could be applied to all iterables, including `Set`. \n</div>","created_at":"2020-07-19T19:02:44.719Z","id":51,"slug":"what-are-collections-and-iterables","title":"What are collections (and iterables)?","tutorial":6,"updated_at":"2020-07-20T15:25:00.824Z"},{"author":1,"content":"An `iterator` is an interface for getting items, one at a time, from an object. All `Iterable` types have iterators. Iterators, in reality, are just objects that tell Dart in what order to access objects one at a time. This is what allows us to use language features like `for in` loops.  This all feels very hand-wavy to type, so let's look at some examples to show you what I mean.\n\nThe code example will probably make the most sense if you first understand what the goal is. \n\nSuppose you want to make a `Grid` class. The grid class will represent data that looks like this:\n\n```\n[\n [ 0, 1, 2],\n [ 3, 4, 5],\n [ 6, 7, 8],\n]\n```\n\n\nSo, it's just a list of lists. Nothing special, until you want to be able to do this on it:\n\n```dart\nfor (var point in grid) {\n  print(point);  \n}\n\n// and you expect that to print this:\n// => 0\n// => 1\n// => 2\n// => 3\n// => 4\n// => 5\n// => 6\n// => 7\n// => 8\n```\n\nIn otherwords, you want it to be smart enough to wrap to the next line when you hit the end of any given horizontal like. That'd be pretty neat. This (large) code example shows how you could achieve that:\n\nI explain the code below, if you'd rather see the explanation first.\n\n<pre>\n    <code class=\"language-run-dartpad:theme-light:mode-dart:split-60:width-100%:height-500px\">\n\nclass Point &lt;T> {\n  final int x;\n  final int y;\n  final T value;\n\n  Point(this.x, this.y, this.value);\n\n  String toString() => \"($x, $y), value: $value\";\n}\n\nclass Grid&lt;T> with IterableMixin&lt;Point&lt;T>> {\n  List&lt;List&lt;Point>> _grid;\n\n  Grid() : _grid = &lt;List&lt;Point>>[];\n\n  factory Grid.fromNestedList(List&lt;List&lt;T>> grid) {\n    final _new = &lt;List&lt;Point&lt;T>>>[];\n    for (var i = 0; i &lt; grid.length; i++) {\n      _new.add(&lt;Point&lt;T>>[]);\n      for (var j = 0; j &lt; grid.length; j++) {\n        _new[i].add(Point&lt;T>(i, j, grid[i][j]));\n      }\n    }\n\n    return Grid().._grid = _new;\n  }\n\n  @override\n  Iterator&lt;Point&lt;T>> get iterator => GridIterator(_grid);\n}\n\nclass GridIterator&lt;T> extends Iterator&lt;Point&lt;T>> {\n  GridIterator(this._grid) {\n    _crossAxisCount = _grid[0].length - 1;\n    _verticalAxisCount = _grid.length - 1;\n  }\n\n  int _iIndex = -1;\n  int _jIndex = -1;\n\n  int _crossAxisCount;\n  int _verticalAxisCount;\n  final List&lt;List&lt;Point>> _grid;\n\n  @override\n  Point&lt;T> get current {\n    if (_iIndex &lt; 0) return null;\n    if (_jIndex &lt; 0) return null;\n    if (_iIndex > _crossAxisCount) return null;\n    if (_jIndex > _verticalAxisCount) return null;\n    return _grid[_jIndex][_iIndex];\n  }\n\n  @override\n  bool moveNext() {\n    if (_iIndex &lt; _crossAxisCount) {\n      _iIndex++;\n    } else {\n      if (_jIndex &lt;= _verticalAxisCount) {\n        _iIndex = 0;\n        _jIndex++;\n      }\n    }\n\n    if (_jIndex > _verticalAxisCount) {\n      return false;\n    }\n\n    return true;\n  }\n}\n\nvoid main() {\n  Grid grid = Grid.fromNestedList([\n    [1, 2, 3],\n    [4, 5, 6],\n    [7, 8, 9]\n  ]);\n\n  for (var point in grid) {\n    print(point);\n  }\n}\n</code></pre>\n\nImportant pieces of the code:\n\n- Make a class that `extends IterableMixin`. This forces the class to implement a getter called `iterator`. That iterator must return an... `Iterator`.\n- Next, create a class that implements that extends that `Iterator`. This class must contain two methods:\n   - `T current()` \n        - this should return the current element in your class in any given iteration of a loop.\n        - for example, when you write `for (var point in grid)`, `point` is what is returned by `Iterator.current`. \n   - `bool moveNext`  \n        - this is called internally at the end of every iteration of a loop. It determines what the next `current` is.\n        \nThis code may seem complex (because it is), but boy howdy do I encourage you to really _get_ it. If you understand this, it really makes you start realizing that you're fully capable of understand how many features of Dart are implemented under the hood.\n\nIts important to note that you don't _have_ to use iterables under the hood in the class that you're making iterable. You could do this if you really wanted:\n\n```dart\nclass User extends IterableMixin<dynamic> {\n  final String name;\n  final int age;\n  final String address;\n  final String username;\n  // etc              \n}\n\n/// and then write the iterator class, which I'm skipping\n/// and eventually have functionality like this:\n \nfor (var prop in user) {\n  print(prop)\n}\n\n// prints \n// 'Eric'\n// 29\n// 'Portland OR'\n// 'ericwindmill'\n```\n\nTo be sure, I don't know why you would want to do that, but you certainly could write an iterator that did this. Because, to recap, all an iterator _really_ does is give us a way to visit elements of an object one at a time, in a specific order.\n\n","created_at":"2020-07-19T19:48:27.567Z","id":61,"slug":"iterators-understanding-and-creating-your-own","title":"Iterators: understanding and creating your own","tutorial":6,"updated_at":"2020-07-26T15:07:37.269Z"},{"author":1,"content":"Among the many methods included on the iterable class are some getters that provide quick, basic information.\n\nFor reading values directly, outside of loops, there are three basic methods.\n\n1. Bracket notation\n2. `Iterable.first`\n3. `Iterable.last`\n\nBracket notation is similar to every language, and first and last do just what they describe: return the first element of a list and the last element of a list, respectively.\n\nThese are useful in many cases, but mainly just make code more readable.  \n\n<pre>\n    <code class=\"language-run-dartpad:theme-light:mode-dart:split-60:width-100%:height-500px\">\nList<String> favoriteCats = ['Nora', 'Phoebe', 'Wallace'];\nvoid main() {\n    print(favoriteCats.first);\n    print(favoriteCats[1]);\n    print(favoriteCats.last);\n}\n</code></pre>\n\nImportantly, none of these methods change the list. They don't remove and return the first or last element. Rather, they're more akin to \"peek\" in other languages.\n","created_at":"2020-07-19T19:33:03.485Z","id":53,"slug":"reading-elements-pt-1-first-last","title":"Reading elements pt 1: first, last","tutorial":6,"updated_at":"2020-07-20T15:25:00.824Z"},{"author":1,"content":"Again, these methods are all methods on _lists_, some of which will also exist on iteratbles, sets, and other collections. For the sake of simplicity, though, it's best to focus on lists.\n\nThe follow methods are used frequently to remove elements from lists:\n\n1. `clear`\n    - removes every element from the list, but retains the list itself and it's type cast.\n2. `remove(element)`\n    - removes a single element from the list, which is strictly equal to the element passed in.\n3. `removeWhere(callback)`\n    - removes every element in the list that satisfies the test, which is passed in as a callback.\n\nThere are also other methods -- `removeAt`, `removeLast`, and `removeRange`, that behave similarly to remove.\n\nOf these, `clear` is pretty straight-forward, while the other two contain important notes. So, we'll start with a quick example of clear.\n\n<pre>\n    <code class=\"language-run-dartpad:theme-light:mode-dart:split-60:width-100%:height-500px\">\nvoid main() {\n  List<int> favoriteYears = [1990, 2002, 2011];\n  print(favoriteYears); // [1990, 2002, 2011]\n  \n  favoriteYears.clear();\n  print(favoriteYears);\n  print(favoriteYears.runtimeType);\n}\n</code></pre>\n\n#### remove and removeWhere\n\nIf we continue to use an example like above, then `remove` is pretty straight forward.\n\n```dart\nvoid main() {\n  List<int> favoriteYears = [1990, 2002, 2011];\n  print(favoriteYears);\n  \n  favoriteYears.remove(2002);\n  print(favoriteYears);\n}\n```\n\nThis example does what you'd expect. The second time the list is printed, after `remove` is called once, the list will read `[1990, 2011]`. \n\nBut, the example gets a little more complicated when you you're working with objects that aren't primitives. Let's take a look at the following example:\n\n```dart\nclass Pet {\n  Pet(this.name, this.animalType);\n\n  String name;\n  String animalType;\n}\n\nclass AnimalDaycare {\n  AnimalDaycare(this.allPets, this.petsToFeed);\n  \n  final List<Pet> allPets;\n  final List<Pet> petsToFeed;\n\n  void addPet(Pet pet, bool shouldFeed) {\n    allPets.add(pet);\n    if (shouldFeed) petsToFeed.add(pet);\n  } \n\n\n  void feedPet(String petName, {String petType = \"cat\"}) {\n    final newPet = Pet(petName, petType);\n    // pet.feed\n    petsToFeed.remove(newPet);\n  } \n}\n\nvoid main() {\n  var phoebe = Pet('Phoebe', 'cat');\n  var wallace = Pet('Wallace', 'cat');\n  var pepper = Pet('Pepper', 'dog');\n\n  var animalDaycare = AnimalDaycare()\n                  ..addPet(phoebe, true)\n                  ..addPet(wallace, true)\n                  ..addPet(pepper, false);\n}\n\n\n/// in the ui, a user selects which pet to feed based on a list of pets.\n/// but, the list of pets contains names only, so it doesn't bloat the \n/// data layer of the front end\n// ..\n\nvoid _onPetSelectedFromList(String petName, AnimalDaycare daycare) {\n  daycare.feedPet(petName);\n}\n```\n\nWhat's going to happen when `_onPetSelectedFromList` is called? nothing. (at least, nothing noticeable to the user or developer). This is because remove only works on objects that are strictly equal. So even though `remove` is being called on a pet that has the same attributes, it's a different instance of the class.\n\nIn complex apps with lots of data, this is actually a common occasion. It usually occurs when: \n1. You use immutable classes as much as possible.\n2. Your UI is completely separate from your business logic.\n\nThese are both 'best practices' in app building, so you'll likely run into this problem. \n\nDon't take my word for it, though, this is why Dart lists have other methods for removing items. Before we look at those, though, let me round out the example above to show you more functionality of `remove`.\n\n<pre>\n    <code class=\"language-run-dartpad:theme-light:mode-dart:split-60:width-100%:height-500px\">\nclass Pet {\n  Pet(this.name, this.animalType);\n\n  String name;\n  String animalType;\n}\n\nclass AnimalDaycare {\n  AnimalDaycare(this.allPets, this.petsToFeed);\n  \n  final List<Pet> allPets;\n  final List<Pet> petsToFeed;\n\n  void addPet(Pet pet, bool shouldFeed) {\n    allPets.add(pet);\n    if (shouldFeed) petsToFeed.add(pet);\n  } \n\n\n  void feedPet(String petName, {String petType = \"cat\"}) {\n    final newPet = Pet(petName, petType);\n    \n    // changes start here\n    // `remove` returns a boolean indicating whether the object was removed or not\n    // rather than throwing when trying to remove an object that doesn't exist.\n    final didRemove = petsToFeed.remove(newPet); \n    if (!didRemove) print('object not found!');\n  } \n}\n\nvoid main() {\n  var phoebe = Pet('Phoebe', 'cat');\n  var wallace = Pet('Wallace', 'cat');\n  var pepper = Pet('Pepper', 'dog');\n\n  var animalDaycare = AnimalDaycare()\n                  ..addPet(phoebe, true)\n                  ..addPet(wallace, true)\n                  ..addPet(pepper, false);\n\n  animalDaycare.feedPet('Phoebe');\n}\n</code></pre>\n\nAs I mentioned in the comments,  `remove` returns a boolean indicating whether the object was removed or not, rather than throwing when trying to remove an object that doesn't exist.\n\n#### removeWhere and friends\n\nStill, you'll likely finding yourself using `removeWhere` more often than `remove`. This method will remove _every_ object in a list that satisfies a test, passed in as a callback. Taking our previous example, we _could_ remove the cat `Phoebe` from the `petsToFeed` list, even if we only knew hew name, and didn't have the entire object.\n\n```dart \n    // taken from the example above, and modified\n  void feedPet(String petName, {String petType = \"cat\"}) {\n    petsToFeed.removeWhere((Pet pet) => pet.name == petName); \n  } \n```\n\n`removeWhere` accepts a callback as an argument. That callback must return a boolean, and accepts a single element from the list as an argument. It will be called on every element.\n\n<div class=\"aside\">\n    There are several methods on lists that contain the word `where` in their name. These are extremely useful, and all work more or less the same.\n</div> \n\nIn the beginning of this lesson, I mentioned methods like `removeAt`, `removeRange`, and `removeLast`. Briefly, these methods do the following:\n\n- `removeLast`\n    - removes the last element from the list, and returns that element\n- `removeAt(idx)`\n    - removes the element from the list at the given index, and returns that element\n- `removeRange(startIndex, endIndex)`\n    - Removes the objects in the range start inclusive to end exclusive. returns nothing (void)\n    \n    \n### Give it a try:\n\nA stack is an abstract data type that has one main rule: first-in-last-out. In human words, that means that the only element that can be removed from a queue is the element that was inserted most recently. Stacks's can be nicely visualized like this:\n\n<img src=\"https://res.cloudinary.com/duqbhmg9i/image/upload/c_scale,h_525/v1589128636/flutter_by_example/stack_jtohuo.png\" alt=\"stack drawing\"/>\n\nYou can implement a stack by using a list, and removing elements with methods like `remove`, `removeAt`, or (might I suggest) `removeLast`. \n\n<iframe style=\"height:400px;width:100%\" src=\"https://dartpad.dev/embed-inline.html?id=a3e3c3b014b1286e5ee51ad37581cd1f&split=60&theme=dark\"></iframe>\n\n\n","created_at":"2020-07-19T19:37:35.751Z","id":56,"slug":"removing-elements-remove-clear-remove-where","title":"Removing elements: remove, clear, removeWhere","tutorial":6,"updated_at":"2020-07-20T15:25:00.824Z"},{"author":1,"content":"<div class='aside'>\nFor most of the remainder of the section, I'll be using `List`, as its the most common iterable, but most of the knowledge could be applied to all iterables, including `Set`. \n</div>\n\nLists (and iterables and sets) are the primary objects that you'll _loop_ over. You can see basic examples of `for`, `while` and `do-while` loops in the Loops lesson in the Control Flow section. Here, let's take a deeper look at two other looping mechanisms: `for-in` loops and the `forEach` method on iterables.\n\nBoth are used for the same purpose: performing an action on _each_ element in the list. Importantly, both are used primarily for _side effects_. The original list will not be changed, nor will you be returned any new value from these methods.  \n\n### for-in loops\n\nFor-in loops function similarly to standard `for` loops, but there are two differences: \n    1. It easier to write. \n    2. You won't have access, by default, to the index of the element in the list.\n\nFor-in loops are preferable to for loops to me, because they are cleaner, but they don't really solve any problem that standard for loops wont.\n\nThis example shows the syntax for for-in loops, but as you can see there is no built-in way to get the index of the element in the list. It\n\n<pre>\n    <code class=\"language-run-dartpad:theme-light:mode-dart:split-60:width-100%:height-400px\">\nvoid main() {\n   List<int> ages = [29, 27, 42];\n   for (var age in ages) {\n     print(age);\n  }\n}\n</code></pre>\n\n### forEach\n\n`List.forEach` is a looping mechanism that is more difficult to grasp (if you aren't familiar with call backs), and provides very little benefit over using a for-loop.\n\nIt's best to just look at some code:\n\n<pre>\n    <code class=\"language-run-dartpad:theme-light:mode-dart:split-60:width-100%:height-600px\">\nvoid main() {\n   List<int> ages = [29, 27, 42];\n    // the arguement that forEach expects is \n    // a *call back*. This function will be called on\n    // each element\n   ages.forEach((int age) => print(age));\n}\n</code></pre>\n\nThat looks a bit more complex, but does the _exact_ same thing as the first example using `for-in` loop. In fact, look at this example comparing the two.\n\n\n<pre>\n    <code class=\"language-run-dartpad:theme-light:mode-dart:split-60:width-100%:height-600px\">\nvoid main() {\n   List<int> ages = [29, 27, 42];\n    \n    // should print 30, 28, 43\n    for (var age in ages) {\n        _addAndPrint(age);\n    }\n\n    // should print 30, 28, 43\n    ages.forEach((int age) => _addAndPrint(age));\n}\n\nvoid _addAndPrint(int number) {\n    print(1 + number);\n}\n</code></pre>\n\nWhile for-each is more complex to write, it's often favored because of how terse the code looks. For our purposed, it's important because many of the future methods we'll explore on lists and iterables follows this same pattern. \n\n<div class='aside'>\nThese methods that operate on collections are often called _functional_ methods in JavaScript, Dart, and beyond. If you hear someone talking about _functional_ programming in JS, they're likely talking about these specific methods, and not about pure functional programming. These methods are like a piece of functional programming languages that's been borrowed by languages that aren't necessarily functional.\nIn any case, they're used _a lot_ in UI development, so it's good to know them. \n</div>\n\n### Try it yourself: looping\n\n<iframe style=\"height:400px;width:100%;\" src=\"https://dartpad.dev/embed-inline.html?id=510e84f2bf31e395073aff739046d02f&split=60&theme=dark\"></iframe>\n\n\n","created_at":"2020-07-19T19:05:07.612Z","id":52,"slug":"looping-for-in-and-for-each","title":"Looping: for-in and forEach","tutorial":6,"updated_at":"2020-07-20T15:25:00.824Z"},{"author":1,"content":"Often you may need to check that one or more elements exist in an list, and do some logic based on the logic. Dart includes some handy methods to make this easy. \n\n### indexOf\n\nThis is another method that exists on the list, but not sets (because lists care about index, and sets don't necessarily). You may have seen this method in other languages on arrays.\n\n`List.indexOf(element)` returns the index of the given element in the list. If the element doesn't exist, if returns `-1`. That's important, because it doesn't throw an error if the element doesn't exist.\n\n```dart \nList<String> animals = ['fish', 'tiger', 'crow'];\nprint(animals.indexOf('fish'); // 0\nprint(animals.indexOf('elephant'); // -1\n```\n\n### contains\n\n`contains(element)` does exist on the base class of `Iterable`. It returns a boolean based on weather the given element is in the list or not.\n\n```dart\nList<String> animals = ['fish', 'tiger', 'crow'];\nprint(animals.contains('fish'); // true\nprint(animals.contains('elephant'); // false\n``` \n\nThe `Map` collection isn't an iterable, but contains similar methods `containsKey` and `containsValue`. These are mightly useful when keeping track of some data with a map in memory. \n\n```dart\nMap<String, int> favoriteNumbers = {\n'Greg': 3,\n'Stephanie': 7,\n'Alison': 4,\n}\n\n// throws error!\nprint(favoriteNumbers['John']);\n\n// safe!\nif (favoriteNumbers.containsKey('John')) print(favoriteNumbers['John']);\n```\n\n### any and every\n\n\n<div class=\"aside\">\nThis is where working with iterables can become complex if you aren't familiar with callbacks or functional programming. If that's you, don't sweat it. Take your time, take a nap, you'll get it.\n</div>\n\n#### First, a review\n\nFirst, let's take another look at the most 'basic' functional method on iterables: `forEach`. This method will touch every element in the iterable, in order, and call the function you pass in as an argument on each element. It's no different than looping over each element and calling the same function:\n\n<pre>\n    <code class=\"language-run-dartpad:theme-light:mode-dart:split-60:width-100%:height-500px\">\nvoid main() {\n   List<int> ages = [29, 27, 42];\n    \n    // should print 30, 28, 43\n    for (var age in ages) {\n        _addAndPrint(age);\n    }\n\n    // should print 30, 28, 43\n    ages.forEach((int age) => _addAndPrint(age));\n}\n\nvoid _addAndPrint(int number) {\n    print(1 + number);\n}\n</code></pre>\n\n\n<div class=\"aside\">\nOne advantage to using forEach is that you can pass in a function _without_ calling it, and Dart is smart enough to decipher what you're trying to do. \n\n```dart \nages.forEach(_addAndPrint);\n\n// This is *exactly* the same as:\n\nages.forEach((int age) => _addAndPrint(age)); \n```\n\nIf this makes your head spin, don't worry about it. It does nothing but make the code cleaner. \n</div>\n\n#### any\n\n`Iterable.any` is a method that returns true if any single element in the iterable satisfies a 'test' that's passed in as a callback. For example, if you have a list of users and want to find out if any of them are under 18, `any` would be a good method to use.\n\n<pre>\n    <code class=\"language-run-dartpad:theme-light:mode-dart:split-60:width-100%:height-500px\">\nclass User {\n  User(this.name, this.age);\n\n  final String name;\n  final int age;\n}\n\nList<User> users = [\n  User('Zoltan', 55),\n  User('Trey', 19),\n  User('Marsha', 32),\n];\n\nvoid main() {\n  final anyUnder18 = users.any((User u) => u.age < 18);\n\n  if (anyUnder18) {\n    print('Sorry, kid');\n  } else {\n    print('commence party!');\n  }\n}\n</code></pre>\n\n#### every\n\n`Iterable.every` is like any, but returns true if and only if each element in the list satisfies the test passed in as a callback.\n\n<pre>\n    <code class=\"language-run-dartpad:theme-light:mode-dart:split-60:width-100%:height-500px\">\nclass User {\n  User(this.name, this.age);\n\n  final String name;\n  final int age;\n}\n\nList<User> users = [\n  User('Zoltan', 55),\n  User('Trey', 19),\n  User('Marsha', 32),\n];\n\nvoid main() {\n  final allUsersAbleToParty = users.every((User u) => u.age > 18);\n\n  if (allUsersAbleToParty) {\n    print('Sorry, kid');\n  } else {\n    print('commence party!');\n  }\n}\n</code></pre>\n\nAs you can see, these methods are similar. The above functionality was implemented with only two changes. `any` became `every` and `u.age < 18` changed to using a greater than sign.\n\nA real-life use case that you may find for these methods is when checking roles or permissions on a user. For example, can this user make a sale? Well, lets see if they have any of the roles that allow users to make sales. Alternatively, maybe they need _every_ role. \n\nThe following DartPad exercise asks you to implement that feature.\n\n### Try it yourself. Using any and every\n\n<iframe style=\"height:400px;width:100%;\" src=\"https://dartpad.dev/embed-inline.html?id=be19f84e60b97b8dc38633070b7863f1&split=60&theme=dark\"></iframe>\n","created_at":"2020-07-19T19:36:30.859Z","id":55,"slug":"checking-for-elements-contains-index-of-any-every","title":"Checking for elements: contains, indexOf, any, every","tutorial":6,"updated_at":"2020-07-20T15:25:00.824Z"},{"author":1,"content":"Maps have many similar methods and properties as `Iterable` types, but they aren't actually iterable. As a review from a different, earlier lesson on Flutter by Example:\n\n### From Flutter by Example section DataTypes:\n\nA map, also known commonly as a dictionary or hash, is an _unordered_ collection of key-value pairs. Maps pair a key with a value for easy, fast retrieval. Like lists and sets, maps can be declared with a constructor or literal syntax.\n\n<div class='aside'>\n    Sets and maps have the the same syntax for their literal implementation. When you define a set literal, you must annotate the type of the variable. Otherwise, it will default to a `Map`.  \n</div>\n\n```dart\n// literal syntax\nvar dogsIvePet = {\n  'Golden Retriever': ['Cowboy', 'Jack'],\n  'Laberdoodles': ['Wallace', 'Phoebe'], \n  'Shepards': ['Doug', 'Steak'],\n}\n\n// constructor syntax\nvar dogsIWantToPet = Map();\n\n// create a key called 'Border Collie' and assign it's value\ndogsIWantToPet['Border Collie'] = ['Mike', 'Jackson'];\n```\n\n### Iterable like methods on maps\n\nEven though maps are completely different types than Iterables, it's often useful to treat them as iterables. The Map class contains many iterable-like methods on Maps.\n\nI will run through some of these briefly with examples, but these are used similarly to iterables.\n\n<pre>\n    <code class=\"language-run-dartpad:theme-light:mode-dart:split-60:width-100%:height-500px\">\nMap&lt;String, List&lt;String>> dogsIvePet = {\n  'Golden Retriever': ['Cowboy', 'Jack'],\n  'Laberdoodles': ['Wallace', 'Phoebe'], \n  'Shepards': ['Doug', 'Steak'],\n};\n\nvoid main() {\n  /// Map.map()\n  final numberDogsSeenByType = dogsIvePet.map((String type, List&lt;String> names) {\n    return MapEntry&lt;String, int>(type, names.length);\n  });\n  print(numberDogsSeenByType);\n  \n  \n  /// Map.removeWhere()\n  dogsIvePet.removeWhere((String type, List&lt;String> names) {\n    return type.contains('doodle');\n  });\n  print(dogsIvePet);\n  \n  /// Map.containsKey() (there is also containsValue())\n  print(dogsIvePet.containsKey('Shepards'));\n}\n</code></pre>\n\nThese are only a few methods, but there are few things that are map-specific I'd like to note:\n\n- `Map.keys` returns an iterable where the elements are the keys. This can be mighty useful to do complex iterations over maps.\n- `Map.values` does the same, but for values.\n- Finally, `putIfAbsent`, a great method that makes code 'cleaner', and solves a problem you've likely encountered before.\n\nYou've probably seen this before:\n\n```dart\nif (!map.containsKey('myKey')) {\n  map['myKey'] = 'myValue';\n}\n```\n\nThis pattern is often used when you want to insert a pair into a map, unless the key already exists (in which case, inserting the pair would overwrite the original pair);\n\nYou can use the `putIfAbsent` method to make this a bit cleaner.\n\n```dart\nmap.putIfAbsent('myKey', () => 'myValue');\n```\n\nIf the key exists, it won't do anything with the value. In fact, it won't even _create the value in memory_. This is great when the value isn't a string, and rather some complex computation.\n\nThis method also returns the value that is returned from the `ifAbsent` callback, meaning you can do some code-golf-y things like:\n\n```dart\nvar users = {\n 'eric': User(\n    // lots of properties \n  ),\n  'eli': User(\n    // lots of properties\n  ),\n}\n\nUser _createNewUserIfNecessary({String name, int age, String username}) {\n  var newUser = users.putIfAbsent(name, () => User(name, age, username));\n  return newUser ?? users[name];\n}\n```\n\nThis contrived method will return the user you want no matter what, making the function safe to call. But, importantly, it won't do the computation of creating the user if the user already exists.\n","created_at":"2020-07-19T19:49:30.365Z","id":62,"slug":"iterable-like-methods-on-maps-and-put-if-absent","title":"Iterable-like methods on maps (and putIfAbsent)","tutorial":6,"updated_at":"2020-07-26T15:09:16.395Z"},{"author":1,"content":"Often, especially when working with methods on lists and sets, the _type_ of the return list (or elements) is not quite what you need. Iterables in Dart solve this problem by providing several typecasting methods.\n\nThe most straight forward methods are `toList` and `toSet`. And, believe it or not, you will need to use these methods _a lot_ to avoid typing issues if you plan on using and the methods from this tutorial. \n\n`toList` simply turns an iterable into a list, and `toSet` into a set. These are so valuable because most of the functional methods on iteratbles return values of type `Iterable`, _even if they're called on lists_. Let's take a look at `where`, as an example:\n\n```dart\nvoid main() {\n    List<int> ages = [12,17,19,14,21,20,15];\n    final oldEnough = ages.where((int age) => age >= 18);\n    print(oldEnough.runtimeType); // WhereIterable\n}\n```\n\nThe type of that variable is `WhereIterable`, not list. Which is fine in the small example above, but won't be fine if you trying to use it as a list elsewhere in the app.\n\n```dart\nvoid printList(List list) {\n  for (var element in list) {\n    print(element);\n  }\n}\n\nvoid main() {\n    List<int> ages = [12,17,19,14,21,20,15];\n    final oldEnough = ages.where((int age) => age >= 18);\n    printList(oldEnough); // Error! WhereIterable is not of type List\n}\n```\n\nSolving this problem is easy enough, though. Just call `oldEnough.toList()`\n\n\n<pre>\n    <code class=\"language-run-dartpad:theme-light:mode-dart:split-60:width-100%:height-500px\">\nvoid printList(List<int> list) {\n  for (var element in list) {\n    print(element);\n  }\n}\n\nvoid main() {\n    List<int> ages = [12,17,19,14,21,20,15];\n    final oldEnough = ages.where((int age) => age >= 18).toList(); // noice\n    printList(oldEnough); \n}\n</code></pre>\n\n### casting the elements in a list\n\nTurns out, this a topic of much conversation. \n\nSometimes, you have a list of elements that are of a certain type, but you want those elements to be of a different type, in order to make the analyzer happy. To make that more clear, let's walk through an example:\n\n<div class=\"aside\">\nThe first set of examples here has nothing to do with iterables, but explains the keyword `as`. We will transition into working with `as` with iterables.\n</div>\n\nSuppose you have a `User` class that looks like this.\n\n```dart\nclass User {\n  String name;\n  int age;\n}\n```\n\nThis is great, but now your app needs \"roles\", which means different sub-types of Users. Perhaps you now have these classes:\n\n```dart\nclass Manager extends User {\n  void accessEmployeeRecords() {};\n  void accessMyRecord() {}\n}\n\nclass Bartender extends User {\n  void accessMyRecord() {}\n}\n```\n\nThese classes are pretty similar, but the manager can see everyone's records. Imagine an iPad app in which each user has a profile, including their record. Now, to fetch the records, you have a method that expects a `User` as an argument. This is fine, but because `Manager` contains a method that `Bartender` doesn't, you cannot just call `User.accessEmployeeRecords()`, _even if you know in your brain that a manager is passed in_. You must _typecast_ this user as a manager. \n\nThe first example of doing this is with the `as` keyword.\n\n```dart \nvoid accessRecords(User user, bool isManager) {\n   if (isManager) {\n     (user as Manager).accessEmployeeeRecords();\n   }\n\n   user.accessMyRecord();\n}\n```\n\nUsing `as` tells the analyzer that this is okay, that you want to call the method as if this user was a manager.\n\n`as` is considered the \"safest\" form of typecasting in dart, and it is used quite often in Flutter UI, particularly when using the [bloc library](https://pub.dev/packages/bloc).\n\nImportantly, `as` can only cast _down_. So, `User as Manager` is fine, but `Manager as User` is not okay.\n\n### Using `cast`\n\nOne of the other casting keywords, which lives particularly on Iterables, is `cast<T>`. It gives you a new list which _appears_ to be of the type `List<T>`, so that you can use it in places where the analyzer _expects_ `List<T>`, but it doesn't actually change the types of the elements. \n\nRun the example below... what is printed out might surprise you:  \n\n<pre>\n    <code class=\"language-run-dartpad:theme-light:mode-dart:split-60:width-100%:height-500px\">\nvoid main() {\n  List<num> coolNums = [1, 2, 3.1];\n  List<double> coolDoubles = coolNums.cast<double>();\n  \n  printDubs(coolDoubles);\n  \n}\n\nvoid printDubs(List<double> dubs) {\n  for (var d in dubs) {\n    print(d.runtimeType);\n  }\n}</code></pre>\n\n   \nOf course, this feels a bit dangerous, and is hardly ever recommended that you use `cast`.","created_at":"2020-07-19T19:47:16.641Z","id":60,"slug":"type-casting-collections-cast-as-retype-to-set-to-list","title":"Type casting collections: cast, as, retype, toSet, toList","tutorial":6,"updated_at":"2020-07-20T15:25:00.824Z"},{"author":1,"content":"Along with the lesson on `where`, I'd consider `map` the other most important functional method on iterables. At my day job, we use `List.map` _a lot_ in our Flutter UI.\n\nIn a nutshell, `map` is called on a list to generate a _new_ list, where the elements are created by performing an action on each of the original elements. That action is passed in as a callback. \n\nMapping is best explained with an example.\n\nSuppose you are trying to display a list of `Users` in an app. But, you only want to display the user's name. There's a map for that. :} \n\n<pre>\n    <code class=\"language-run-dartpad:theme-light:mode-dart:split-60:width-100%:height-500px\">\nclass User {\n    User(this.name, this.age);\n    final String name; \n    final int age;\n}\n\nvoid main() {\n    final rody = User(\"Rody\", 25);\n    final jorge = User(\"Jorge\", 25);\n    final remi = User(\"Remí\", 25);\n\n    final users = [rody, jorge, remi];\n    final names = users.map((User user) => user.name);\n    print(names);\n}\n</code></pre>\n \nAs mentioned, `map` is used _a lot_ in UI work, which I'll show in a later lesson on iterables in Flutter widgets. This is just a good visual example, though. I think map is used more than most other methods from the Dart SDK in my companies app, throughout the business logic as well.\n\nTo be clear, `map` isn't only useful when changing elements into different types entirely. You could also use it update all the elements in an object:\n\n<pre>\n    <code class=\"language-run-dartpad:theme-light:mode-dart:split-60:width-100%:height-500px\">\nclass User {\n    User(this.name, this.age);\n    final String name; \n    final int age;\n\n    bool isSpecialUser = false;\n  \n    String toString() {\n      return 'User {name: $name, age: $age, isSpecialUser: $isSpecialUser}';\n    }\n\n}\n\nvoid main() {\n    final rody = User(\"Rody\", 25);\n    final jorge = User(\"Jorge\", 25);\n    final remi = User(\"Remí\", 25);\n\n    final newUsers = [rody, jorge, remi];\n    print(newUsers);\n\n    final asSpecialUsers = newUsers.map((User u) => u.isSpecialUser = true);\n    print(asSpecialUsers);\n}\n</code></pre>\n\n### Using expand\n\nExpand is an interesting one. It's not used nearly as much as `map`, but it allows you to change the values in a list in some interesting ways. It has two common use cases:\n\n- flattening nested lists\n- duplicating elements in a list (which you can also change as you're duplicating);\n\nFirst, take a look at the examples from Dart docs. They're contrived, but allow you to see some important points. Then, you'll have the opportunity to give it a try using an actual example from the app that I work on at my day job.\n\n```dart\n/// example ripped directly from the Dart docs.\n/// flattening a list\nvar pairs = [[1, 2], [3, 4]];\nvar flattened = pairs.expand((pair) => pair).toList();\nprint(flattened); // => [1, 2, 3, 4];\n\n/// duplicating elements in a list\nvar input = [1, 2, 3];\n// important! the callback passed to expand must return an iterable!\nvar duplicated = input.expand((i) => [i, i]).toList();\nprint(duplicated); // => [1, 1, 2, 2, 3, 3]\n```\n\nThis example, again, isn't super obvious or helpful for real life. Take a stab at the exercise below, which is inspired by an actual use of `expand` in the app that I work on at my day job.\n\n\n### Try it yourself: expand\n\nSuppose you're building an e-commerce site. Your site has the functionality to show a user everything they've ever purchased. Your data might look like this: \n\n```dart\nclass User {\n  final List<Order> pastOrders;\n  // rest of class\n}\n\nclass Order {\n  final List<Item> itemsInOrder;\n  // rest of class\n}\n\nclass Item {\n  final String name;\n  // rest of class\n}\n```\n\nIn order to show a user which _items_ they've bought, and not _orders_ they've made, you'd likely want to extract each line item from each of their orders. There are many ways to do this, including using `expand`. For this exercise, try to derive that list of line items from the user.\n\n<iframe style=\"height:400px;width:100%;\" src=\"https://dartpad.dev/embed-inline.html?id=e9bfbab75fc99e90bb36b81d94a775cc&split=60&theme=dark\"></iframe>\n","created_at":"2020-07-19T19:44:29.494Z","id":58,"slug":"changing-elements-map-and-expand","title":"Changing elements: map and expand","tutorial":6,"updated_at":"2020-07-20T15:25:00.824Z"},{"author":1,"content":"Filtering elements from a list, for our purposes, means making a new list out of only some of the elements from an original list. There are many different methods that achieve this for different cases. But, one of the most useful methods on lists is  `where`. In addition to `where`, I will discuss `takeWhile` and `skipWhile`.\n\n`where` is used to filter elements from a list which pass a \"test\" passed in in the form of a callback. \n\n<pre>\n  <code class=\"language-run-dartpad:theme-light:mode-dart:split-60:width-100%:height-500px\">\nvoid main() {\n  final words = [\"hot\", \"dog\", \"phone\", \"coffee\", \"pig\"];\n  final threeLetterWords = words.where((String word) { \n      return word.length == 3 \n  });\n  print(threeLetterWords);      \n}\n</code>\n</pre>\n\nImportant notes: \n\n- where returns a _new_ `Iterable` instance, and does not mutate the original list.\n- if no elements pass the \"test\", an empty iterable is returned. It will not throw an error.\n- Some other filtering, where-like methods -- like `singleWhere` and `firstWhere`, _will_ throw an error if no element in the list satisfies the test.\n\n### takeWhile and skipWhile\n\nThese methods also return new `Iterables`, but they return entire sections of the original list, depending on which element in the list satisfies the test. In human words:\n\n- `takeWhile(testCallback)`\n    - this will return every element in a list from index 0 to the element that first satisfies the test.\n- `skipWhile(testCallback)`\n    - this will return every element in a list starting with the first element that passes the test to the final element in the list.\n    \n<pre>\n    <code class=\"language-run-dartpad:theme-light:mode-dart:split-60:width-100%:height-500px\">\nvoid main() {\n  final numsFrom0To5 = [0, 1, 2, 3, 4, 5];\n  final numsTo2 = numsFrom0To5.takeWhile((int n) => n &lt;= 2);\n  print(numsTo2);\n  final numsFrom3To5 = numsFrom0To5.skipWhile((int n) => n &lt;= 2);\n  print(nums);\n}\n  </code>\n</pre>\n\n<div class=\"aside\">\n    As you may have guessed, `takeWhile` and `skipWhile` are extremely useful for _sorted_ lists, but for much else.\n</div> \n\n### Try filtering a list yourself\n\n<iframe style=\"height:400px;width:100%;\" src=\"https://dartpad.dev/embed-inline.html?id=9f5065991b2194a12fc03fbf7c0fc0e3&split=60&theme=dark\"></iframe>","created_at":"2020-07-19T19:40:21.637Z","id":57,"slug":"filtering-elements-where-take-while-and-skip-while","title":"Filtering elements: where, takeWhile, and skipWhile","tutorial":6,"updated_at":"2020-07-26T15:04:21.743Z"}]},"strapiTableOfContents":{"contents":"{\n  \"Dart\": {\n    \"Getting Started with Dart\": [\n      \"About Dart\",\n      \"Install Dart on your machine\",\n      \"Dartpad\",\n      \"Text Editors: Intellij and VSCode\",\n      \"Resources: Documentation and Pub.dev\",\n      \"Hello World\",\n      \"The main function\",\n      \"Print to the console\"\n    ],\n    \"Dart Fundamentals\": [\n      \"Values and variables\",\n      \"Comments\",\n      \"const and final variables\",\n      \"Arithmetic and Comparison Operators\",\n      \"Assignment Operators\",\n      \"Logical Operators\",\n      \"Null Aware Operators\",\n      \"Type Test Operators\",\n      \"Bitwise and Shift Operators\",\n      \"Control Flow: if, else, else if\",\n      \"Switch statements and case\",\n      \"Ternary Conditional operator\",\n      \"Loops: for and while\",\n      \"Anatomy of Dart Functions\",\n      \"Arrow functions\",\n      \"Function arguments: default, optional, named\",\n      \"Lexical Scope\",\n      \"Cascade notation\"\n    ],\n    \"Data Types\": [\n      \"Intro to Dart's Type System\",\n      \"Numbers\",\n      \"Strings\",\n      \"Booleans\",\n      \"dynamic\",\n      \"lists\",\n      \"sets\",\n      \"maps\"\n    ],\n    \"Object-Oriented Programming\": [\n      \"Intro to OOP\",\n      \"Classes\",\n      \"Constructors\",\n      \"Properties and methods\",\n      \"Methods: static, private, etc\",\n      \"Getters and setters\",\n      \"Extending classes (inheritance)\",\n      \"Initializer lists and final properties\",\n      \"Factory methods\",\n      \"Singletons\",\n      \"Abstract classes (and interfaces)\",\n      \"Mixins\",\n      \"Extension methods\"\n    ],\n    \"Iterables, Iterators, and Collections\": [\n      \"What are collections (and iterables)?\",\n      \"Looping: for-in and forEach\",\n      \"Reading elements pt 1: first, last\",\n      \"Adding elements: add and insert (all)\",\n      \"Checking for elements: contains, indexOf, any, every\",\n      \"Removing elements: remove, clear, removeWhere\",\n      \"Filtering elements: where, takeWhile, and skipWhile\",\n      \"Changing elements: map and expand\",\n      \"Deriving values from elements: fold, reduce, join\",\n      \"Type casting collections: cast, as, retype, toSet, toList\",\n      \"Iterators: understanding and creating your own\",\n      \"Iterable-like methods on maps (and putIfAbsent)\"\n    ]\n  },\n  \"Flutter\": {\n    \"Getting started with Flutter\": [\n      \"About Flutter\",\n      \"IDEs and resources\"\n    ],\n    \"Widgets\": [\n      \"Intro to Widgets\",\n      \"Widget types: Stateful and Stateless\",\n      \"StatefulWidget lifecycle\",\n      \"The Widget tree\",\n      \"BuildContext\",\n      \"Inherited Widgets\",\n      \"Thinking in widgets\"\n    ],\n    \"Intro Flutter App\": [\n      \"Intro and Setup\",\n      \"Data Model and HTTP\",\n      \"Build a custom widget\",\n      \"ListView and builder pattern\",\n      \"Gradient Backgrounds\",\n      \"Routing: Add a detail page\",\n      \"Routing 2: Add a form page\",\n      \"User Input\",\n      \"Sliders and Buttons\",\n      \"Snackbars and Dialogs\",\n      \"Built-in Animation: AnimatedCrossFade\",\n      \"Built-in Animation: Hero transition\"\n    ],\n    \"Custom Animation: Progress Indicator\": [\n      \"Intro and Overview\",\n      \"Build the example app boiler-plate\",\n      \"Custom Widget: Peg\",\n      \"Tween and AnimationController classes\",\n      \"Tween by example\",\n      \"Using Tweens and Intervals\",\n      \"Wrap the Pegs in AnimatedWidgets\",\n      \"Bring it all together\"\n    ],\n    \"State Management: Blocs without Libraries\": [\n      \"What are blocs?\",\n      \"Calendar App introduction\",\n      \"Create bloc one\",\n      \"Create a bloc provider\",\n      \"Using StreamBuilders with blocs\",\n      \"Create bloc two: Add/Edit Tasks\",\n      \"Consume the second bloc's streams\",\n      \"Complete source code\"\n    ],\n    \"State Management: Provider\": [\n      \"What is Provider?\",\n      \"The most basic example using Provider\",\n      \"ChangeNotifierProvider\",\n      \"Rebuilding widgets with Consumer\",\n      \"Finer build control with Selector\",\n      \"Future Provider\",\n      \"MultiProvider micro lesson\",\n      \"Stream Provider\",\n      \"Using context extensions for more control\",\n      \"ProxyProvider\",\n      \"Using .value constructors\",\n      \"The final example (A shopping cart app)\",\n      \"For the curious: How is provider implemented\"\n    ],\n    \"Handling Data with Brick: Offline First with Rest\": [\n      \"About Brick and setup\",\n      \"Adding a Repository\",\n      \"Adding a Model\",\n      \"Generating Code\",\n      \"Rendering Models\",\n      \"Adding an Association\"\n    ]\n  }\n}"}},"pageContext":{"slug":"looping-for-in-and-for-each","tutorialTitle":"Iterables, Iterators, and Collections","previous":{"author":1,"content":"Again, these methods are all methods on _lists_, some of which will also exist on iteratbles, sets, and other collections. For the sake of simplicity, though, it's best to focus on lists.\n\nThe follow methods are used frequently to remove elements from lists:\n\n1. `clear`\n    - removes every element from the list, but retains the list itself and it's type cast.\n2. `remove(element)`\n    - removes a single element from the list, which is strictly equal to the element passed in.\n3. `removeWhere(callback)`\n    - removes every element in the list that satisfies the test, which is passed in as a callback.\n\nThere are also other methods -- `removeAt`, `removeLast`, and `removeRange`, that behave similarly to remove.\n\nOf these, `clear` is pretty straight-forward, while the other two contain important notes. So, we'll start with a quick example of clear.\n\n<pre>\n    <code class=\"language-run-dartpad:theme-light:mode-dart:split-60:width-100%:height-500px\">\nvoid main() {\n  List<int> favoriteYears = [1990, 2002, 2011];\n  print(favoriteYears); // [1990, 2002, 2011]\n  \n  favoriteYears.clear();\n  print(favoriteYears);\n  print(favoriteYears.runtimeType);\n}\n</code></pre>\n\n#### remove and removeWhere\n\nIf we continue to use an example like above, then `remove` is pretty straight forward.\n\n```dart\nvoid main() {\n  List<int> favoriteYears = [1990, 2002, 2011];\n  print(favoriteYears);\n  \n  favoriteYears.remove(2002);\n  print(favoriteYears);\n}\n```\n\nThis example does what you'd expect. The second time the list is printed, after `remove` is called once, the list will read `[1990, 2011]`. \n\nBut, the example gets a little more complicated when you you're working with objects that aren't primitives. Let's take a look at the following example:\n\n```dart\nclass Pet {\n  Pet(this.name, this.animalType);\n\n  String name;\n  String animalType;\n}\n\nclass AnimalDaycare {\n  AnimalDaycare(this.allPets, this.petsToFeed);\n  \n  final List<Pet> allPets;\n  final List<Pet> petsToFeed;\n\n  void addPet(Pet pet, bool shouldFeed) {\n    allPets.add(pet);\n    if (shouldFeed) petsToFeed.add(pet);\n  } \n\n\n  void feedPet(String petName, {String petType = \"cat\"}) {\n    final newPet = Pet(petName, petType);\n    // pet.feed\n    petsToFeed.remove(newPet);\n  } \n}\n\nvoid main() {\n  var phoebe = Pet('Phoebe', 'cat');\n  var wallace = Pet('Wallace', 'cat');\n  var pepper = Pet('Pepper', 'dog');\n\n  var animalDaycare = AnimalDaycare()\n                  ..addPet(phoebe, true)\n                  ..addPet(wallace, true)\n                  ..addPet(pepper, false);\n}\n\n\n/// in the ui, a user selects which pet to feed based on a list of pets.\n/// but, the list of pets contains names only, so it doesn't bloat the \n/// data layer of the front end\n// ..\n\nvoid _onPetSelectedFromList(String petName, AnimalDaycare daycare) {\n  daycare.feedPet(petName);\n}\n```\n\nWhat's going to happen when `_onPetSelectedFromList` is called? nothing. (at least, nothing noticeable to the user or developer). This is because remove only works on objects that are strictly equal. So even though `remove` is being called on a pet that has the same attributes, it's a different instance of the class.\n\nIn complex apps with lots of data, this is actually a common occasion. It usually occurs when: \n1. You use immutable classes as much as possible.\n2. Your UI is completely separate from your business logic.\n\nThese are both 'best practices' in app building, so you'll likely run into this problem. \n\nDon't take my word for it, though, this is why Dart lists have other methods for removing items. Before we look at those, though, let me round out the example above to show you more functionality of `remove`.\n\n<pre>\n    <code class=\"language-run-dartpad:theme-light:mode-dart:split-60:width-100%:height-500px\">\nclass Pet {\n  Pet(this.name, this.animalType);\n\n  String name;\n  String animalType;\n}\n\nclass AnimalDaycare {\n  AnimalDaycare(this.allPets, this.petsToFeed);\n  \n  final List<Pet> allPets;\n  final List<Pet> petsToFeed;\n\n  void addPet(Pet pet, bool shouldFeed) {\n    allPets.add(pet);\n    if (shouldFeed) petsToFeed.add(pet);\n  } \n\n\n  void feedPet(String petName, {String petType = \"cat\"}) {\n    final newPet = Pet(petName, petType);\n    \n    // changes start here\n    // `remove` returns a boolean indicating whether the object was removed or not\n    // rather than throwing when trying to remove an object that doesn't exist.\n    final didRemove = petsToFeed.remove(newPet); \n    if (!didRemove) print('object not found!');\n  } \n}\n\nvoid main() {\n  var phoebe = Pet('Phoebe', 'cat');\n  var wallace = Pet('Wallace', 'cat');\n  var pepper = Pet('Pepper', 'dog');\n\n  var animalDaycare = AnimalDaycare()\n                  ..addPet(phoebe, true)\n                  ..addPet(wallace, true)\n                  ..addPet(pepper, false);\n\n  animalDaycare.feedPet('Phoebe');\n}\n</code></pre>\n\nAs I mentioned in the comments,  `remove` returns a boolean indicating whether the object was removed or not, rather than throwing when trying to remove an object that doesn't exist.\n\n#### removeWhere and friends\n\nStill, you'll likely finding yourself using `removeWhere` more often than `remove`. This method will remove _every_ object in a list that satisfies a test, passed in as a callback. Taking our previous example, we _could_ remove the cat `Phoebe` from the `petsToFeed` list, even if we only knew hew name, and didn't have the entire object.\n\n```dart \n    // taken from the example above, and modified\n  void feedPet(String petName, {String petType = \"cat\"}) {\n    petsToFeed.removeWhere((Pet pet) => pet.name == petName); \n  } \n```\n\n`removeWhere` accepts a callback as an argument. That callback must return a boolean, and accepts a single element from the list as an argument. It will be called on every element.\n\n<div class=\"aside\">\n    There are several methods on lists that contain the word `where` in their name. These are extremely useful, and all work more or less the same.\n</div> \n\nIn the beginning of this lesson, I mentioned methods like `removeAt`, `removeRange`, and `removeLast`. Briefly, these methods do the following:\n\n- `removeLast`\n    - removes the last element from the list, and returns that element\n- `removeAt(idx)`\n    - removes the element from the list at the given index, and returns that element\n- `removeRange(startIndex, endIndex)`\n    - Removes the objects in the range start inclusive to end exclusive. returns nothing (void)\n    \n    \n### Give it a try:\n\nA stack is an abstract data type that has one main rule: first-in-last-out. In human words, that means that the only element that can be removed from a queue is the element that was inserted most recently. Stacks's can be nicely visualized like this:\n\n<img src=\"https://res.cloudinary.com/duqbhmg9i/image/upload/c_scale,h_525/v1589128636/flutter_by_example/stack_jtohuo.png\" alt=\"stack drawing\"/>\n\nYou can implement a stack by using a list, and removing elements with methods like `remove`, `removeAt`, or (might I suggest) `removeLast`. \n\n<iframe style=\"height:400px;width:100%\" src=\"https://dartpad.dev/embed-inline.html?id=a3e3c3b014b1286e5ee51ad37581cd1f&split=60&theme=dark\"></iframe>\n\n\n","created_at":"2020-07-19T19:37:35.751Z","id":56,"slug":"removing-elements-remove-clear-remove-where","title":"Removing elements: remove, clear, removeWhere","tutorial":6,"updated_at":"2020-07-20T15:25:00.824Z"},"next":{"author":1,"content":"Often you may need to check that one or more elements exist in an list, and do some logic based on the logic. Dart includes some handy methods to make this easy. \n\n### indexOf\n\nThis is another method that exists on the list, but not sets (because lists care about index, and sets don't necessarily). You may have seen this method in other languages on arrays.\n\n`List.indexOf(element)` returns the index of the given element in the list. If the element doesn't exist, if returns `-1`. That's important, because it doesn't throw an error if the element doesn't exist.\n\n```dart \nList<String> animals = ['fish', 'tiger', 'crow'];\nprint(animals.indexOf('fish'); // 0\nprint(animals.indexOf('elephant'); // -1\n```\n\n### contains\n\n`contains(element)` does exist on the base class of `Iterable`. It returns a boolean based on weather the given element is in the list or not.\n\n```dart\nList<String> animals = ['fish', 'tiger', 'crow'];\nprint(animals.contains('fish'); // true\nprint(animals.contains('elephant'); // false\n``` \n\nThe `Map` collection isn't an iterable, but contains similar methods `containsKey` and `containsValue`. These are mightly useful when keeping track of some data with a map in memory. \n\n```dart\nMap<String, int> favoriteNumbers = {\n'Greg': 3,\n'Stephanie': 7,\n'Alison': 4,\n}\n\n// throws error!\nprint(favoriteNumbers['John']);\n\n// safe!\nif (favoriteNumbers.containsKey('John')) print(favoriteNumbers['John']);\n```\n\n### any and every\n\n\n<div class=\"aside\">\nThis is where working with iterables can become complex if you aren't familiar with callbacks or functional programming. If that's you, don't sweat it. Take your time, take a nap, you'll get it.\n</div>\n\n#### First, a review\n\nFirst, let's take another look at the most 'basic' functional method on iterables: `forEach`. This method will touch every element in the iterable, in order, and call the function you pass in as an argument on each element. It's no different than looping over each element and calling the same function:\n\n<pre>\n    <code class=\"language-run-dartpad:theme-light:mode-dart:split-60:width-100%:height-500px\">\nvoid main() {\n   List<int> ages = [29, 27, 42];\n    \n    // should print 30, 28, 43\n    for (var age in ages) {\n        _addAndPrint(age);\n    }\n\n    // should print 30, 28, 43\n    ages.forEach((int age) => _addAndPrint(age));\n}\n\nvoid _addAndPrint(int number) {\n    print(1 + number);\n}\n</code></pre>\n\n\n<div class=\"aside\">\nOne advantage to using forEach is that you can pass in a function _without_ calling it, and Dart is smart enough to decipher what you're trying to do. \n\n```dart \nages.forEach(_addAndPrint);\n\n// This is *exactly* the same as:\n\nages.forEach((int age) => _addAndPrint(age)); \n```\n\nIf this makes your head spin, don't worry about it. It does nothing but make the code cleaner. \n</div>\n\n#### any\n\n`Iterable.any` is a method that returns true if any single element in the iterable satisfies a 'test' that's passed in as a callback. For example, if you have a list of users and want to find out if any of them are under 18, `any` would be a good method to use.\n\n<pre>\n    <code class=\"language-run-dartpad:theme-light:mode-dart:split-60:width-100%:height-500px\">\nclass User {\n  User(this.name, this.age);\n\n  final String name;\n  final int age;\n}\n\nList<User> users = [\n  User('Zoltan', 55),\n  User('Trey', 19),\n  User('Marsha', 32),\n];\n\nvoid main() {\n  final anyUnder18 = users.any((User u) => u.age < 18);\n\n  if (anyUnder18) {\n    print('Sorry, kid');\n  } else {\n    print('commence party!');\n  }\n}\n</code></pre>\n\n#### every\n\n`Iterable.every` is like any, but returns true if and only if each element in the list satisfies the test passed in as a callback.\n\n<pre>\n    <code class=\"language-run-dartpad:theme-light:mode-dart:split-60:width-100%:height-500px\">\nclass User {\n  User(this.name, this.age);\n\n  final String name;\n  final int age;\n}\n\nList<User> users = [\n  User('Zoltan', 55),\n  User('Trey', 19),\n  User('Marsha', 32),\n];\n\nvoid main() {\n  final allUsersAbleToParty = users.every((User u) => u.age > 18);\n\n  if (allUsersAbleToParty) {\n    print('Sorry, kid');\n  } else {\n    print('commence party!');\n  }\n}\n</code></pre>\n\nAs you can see, these methods are similar. The above functionality was implemented with only two changes. `any` became `every` and `u.age < 18` changed to using a greater than sign.\n\nA real-life use case that you may find for these methods is when checking roles or permissions on a user. For example, can this user make a sale? Well, lets see if they have any of the roles that allow users to make sales. Alternatively, maybe they need _every_ role. \n\nThe following DartPad exercise asks you to implement that feature.\n\n### Try it yourself. Using any and every\n\n<iframe style=\"height:400px;width:100%;\" src=\"https://dartpad.dev/embed-inline.html?id=be19f84e60b97b8dc38633070b7863f1&split=60&theme=dark\"></iframe>\n","created_at":"2020-07-19T19:36:30.859Z","id":55,"slug":"checking-for-elements-contains-index-of-any-every","title":"Checking for elements: contains, indexOf, any, every","tutorial":6,"updated_at":"2020-07-20T15:25:00.824Z"}}},"staticQueryHashes":["2185715291","3564968493","63159454"]}