Iterables And Iterators in JavaScript - I
Tags: javascript, webdev, programming
Published: 2021-03-28 19:48:33

An iterable is an object with properties that we can iterate over. This means that we can do some repetitive task based on the properties of the object e.g looping through an array. This might sound awkward, however if you inspect the properties of a array (using console.log) you will find out that arrays have a prototype property. This is undefined by default when we create an instance of an array. 

```javascript
const myArr = []
console.log(myArr.prototype) 
// undefined
```
We can take advantage of this by creating an object with properties and setting the prototype property of the array to point at that object.
If we use the following methods; object.keys(), object.values on an array and the results we get is quite intriguing

```javascript
const arr = ['foo', 'bar', 'john', 'doe']

console.log(Object.keys(arr))
// ["0", "1", "2", "3"]
console.log(Object.values(arr))
// ['foo', 'bar', 'john', 'doe']
```
This further proves that array are still objects, 
The reason we can use a for of loop on an array is because it has a Symbol.iterator method.

### Symbol.iterator
This method is common to all iterables and indeed it the method we attach to an object when we want to make it iterable. Back to arrays. Arrays are data structures that store an item in a particular position which is the index of that item. 
We can create an array by any of the following methods

## Array literal
We just create an array literal which is an array that contains 0 or more items.
```javascript
// Array Literal
const arr = []
```
## from another iterable
```javascript
const arr = Array.from("supermam")
comsole.log(arr)
//  ["s", "u", "p", "e", "r", "m", "a", "n"]
```
## Of different things
```javascript
const arr = Array.of(1,2,3,4)
console.log(arr)
// [1,2,3,4]
```
## Adding items to an Array
We can add items to an array by either adding that item to a particular index in the array or we use array.push to add to the end of the array. We can also use array.unshift to add to the beginning.
```javascript
const arr = []
arr[0] = 'foo' // adding an item to an index
arr.push('bar') // adding to the end
console. log(arr) // ['foo', 'bar']
arr.unshift('john') // adding to the beginning
console.log(arr) // ['john', 'foo', 'bar']
```
## Retrieving items from an array
We can get an item from an array by using the index of the item, we can use array.find.
```javascript
// from the index of the item
const arr = [5, 8, 7, 9]
console.log(arr[2]) // 7

// array.find()
const item = arr.find(num => num === 5)
console.log(item) // 5
```
### iterating over array
we can iterate over an array by using the for of loop, this method can be used to iterare over all iterables, we can also use array.forEach();
```javascript
const arr = [2, 5, 7, 9, 10]
// for of
for(i of arr){
console.log(i)
}

// array.forEach
arr.forEach(item => console.log(item))
```
## Maps
Maps are objects that we can store key-value pairs in, a map is similar to an object, however the main difference between an Object and a map is;
* maps keeps track of the order in which we add properties over the map object.
* maps are iterables, this means that they have a [Symbol.iterator] function and we can use a for of loop on a map object.
* maps have no properties defined on them when we create them, and it will only contain those properties we add on them.

```javascript
// creating a map Object
const heroMap = new Map() // new map object
console.log(heroMap) // Map {}
```
We add properties to our map object using the set method, 
```javascript
heroMap.set('superman', {name: 'superman', alias: 'clak kent'} )

heroMap.set('batman', {name: 'batman', alias: 'bruce wayne'})
```
The set function accepts two parameters, one is the key, while the other is the value we want to set for that key.
To check if a key exist on a map object we use the has method, this method returns the true for the key we pass to it if that key exists on the map object, however if that key does not exist on tbe object it will return undefined.

```javascript
heroMap.has("superman") // true
heroMap.has('spiderman') // undefined
heroMap.has("batman") // true
```
If we want to get a value from the map object we use the get() method, we pass in the key whose value we want to the get method.
```javascript
console.log(heroMap.get('superman') )
//  {name: 'superman', alias: 'clak kent'} 

console.log(heroMap.get('batman'))
// {name: 'batman', alias: 'bruce wayne'}
```
We can iterate over a map using a for of loop

```javascript
for(k of heroMap)
{
 console.log(k)
}

// ['superman', {name: 'superman', alias: 'clak kent'}]
// ['batman', {name: 'batman', alias: 'bruce wayne'}]

// you can also use this on a map
heroMap.forEach( item => console.log(item))
// superman
// spiderman

// returns us a new iterator object  
const keys = Object.keys(heroMap)
console.log(keys.next().value)
// superman

// more on this later
```

## Sets
Sets are iterables that we can use to store a collection of unique items, we can store just about any data in a set but each has to be unique;

We can create a set by invoking the Set constructor.
```javascript
const mySet = new Set()
```

To add properties to a set we use the the set.add method, it accepts a parameter which is the item we want to add to the set
```javascript
mySet.add(2)
mySet.add(4)
mySet.add('even numbers')
```
To check if a value exist in a set we can use the set.has() Method, we pass in the value we want to check for its existence as an argument to the has function.

```javascript
mySet.has("even numbers") // true
mySet.has(2) // true
mySet.has(3) // false
mySet.has(4) // true
```
We can retrieve the values in a set by using the for of method since sets are iterables we can use the for of method to iterate over a set to obtain the values inside the set

```javascript
for (k of mySet) {
console.log(k)
}

// 2
// 4
// even numbers

set.forEach(num => console.log(num))
// 2
// 4
// even numbers
```
A set is great idea for storing unique collection of data like an a list of uid (unique id).
When we retrieve the properties from a set we get it back in the order we stored it, FIFO. 

We just briefly touched iterables, There are other iterables in JavaScript, we can also create our own custom iterable all which we discuss in subsequent posts.

Hope you found this useful