Aguarde...

8 de novembro de 2021

Uma introdução simples aos iteradores JavaScript

Uma introdução simples aos iteradores JavaScript

Iteradores são estruturas de dados que permitem processar uma sequência de elementos com mais eficiência. Este tutorial o ajudará a aprender sobre o que são iteradores JavaScript e como descobrir se algo é um iterador. Você também aprenderá sobre os tipos existentes de iteradores, seus consumidores e como trabalhar com eles.

Uma rápida introdução aos iteradores JavaScript

Um iterador é um tipo de estrutura de dados. É uma coleção de elementos. Dois exemplos dessas coleções são strings e arrays. O primeiro, string é uma coleção de caracteres. O segundo, array é uma coleção de itens. Dito isso, nem toda coleção é um iterador.

Para que uma coleção seja um iterador, ela deve estar em conformidade com a especificação da Iterableinterface. Essa interface diz que as coleções devem implementar um método Symbol.iterator . Isso significa que esse método deve estar disponível no objeto da coleção. Este método, quando invocado, retorna um objeto Iterator .

Este Iteratorobjeto contém um método chamado next(). Este método retorna um objeto com duas propriedades valuedone. A valuepropriedade contém o item da coleção que está atualmente na sequência de iteração. O doneé um booleano que informa se a iteração está no final.

Podemos usar esse next()método para iterar na coleção de maneira controlada. Ao contrário do loop for ou do método map, em que não podemos parar e retomar a iteração, os iteradores JavaScript nos permitem fazer isso. Eles nos permitem obter cada item da coleção, para retomar a iteração, quando quisermos.

// Create an array:
const list = [1, 3, 5, 7, 9]
// Create iterator for "list" array:
const listIterator = list[Symbol.iterator]()

// Log the iterator object:
console.log(listIterator)
// Output:
// Iterator [Array Iterator] { __proto__: { next: ƒ next() } }

// Try next() method:
listIterator.next()
// Output:
// { value: 1, done: false }

listIterator.next()
// Output:
// { value: 3, done: false }

listIterator.next()
// Output:
// { value: 5, done: false }

listIterator.next()
// Output:
// { value: 7, done: false }

listIterator.next()
// Output:
// { value: 9, done: false }

listIterator.next()
// Output:
// { value: undefined, done: true }

Tipos de iteradores JavaScript

Atualmente, existem quatro tipos de dados em JavaScript que são iteráveis. Esses tipos iteráveis ​​são strings, arrays, mapas e conjuntos.

Cordas

A ideia de que a string pode ser iterável pode parecer estranha. No entanto, é verdade. Podemos validar isso com um teste simples. Se string for iterável, deve ter o método Symbol.iterator . Se invocarmos esse método, devemos obter o objeto iterador. Com este objeto, devemos também obter o next()método.

// Create a string and iterator object for it:
const str = 'It worked'
const strIterator = str[Symbol.iterator]()

// Iterate over individual characters with next():
strIterator.next()
// Output:
// { value: 'I', done: false }

strIterator.next()
// Output:
// { value: 't', done: false }

strIterator.next()
// Output:
// { value: ' ', done: false }

strIterator.next()
// Output:
// { value: 'w', done: false }


// Iterate over the string using for...of loop:
for (const char of str) {
  console.log(char);
}
// Output:
// 'I'
// 't'
// ' '
// 'w'
// 'o'
// 'r'
// 'k'
// 'e'
// 'd'

Matrizes

Arrays são o segundo tipo iterável. Novamente, podemos testar isso usando o método e o loop Symbol.iteratorfor...of .

// Create an array and iterator object for it:
const names = ['Josh', 'Howard', 'Lucy', 'Victoria']
const namesIterator = names[Symbol.iterator]()

// Iterate over individual items with next():
namesIterator.next()
// Output:
// { value: 'Josh', done: false }

namesIterator.next()
// Output:
// { value: 'Howard', done: false }

namesIterator.next()
// Output:
// { value: 'Lucy', done: false }

namesIterator.next()
// Output:
// { value: 'Victoria', done: false }


// Iterate over the array using for...of loop:
for (const name of names) {
  console.log(name);
}
// Output:
'Josh'
'Howard'
'Lucy'
'Victoria'

Mapas

O terceiro tipo iterável é o objeto Map . Com o Maps, podemos iterar seus pares de chave e valor.

// Create a Map and iterator object for it:
const map = new Map()
map.set('name', 'Tony Stark')
map.set('alias', 'Iron Man')
map.set('reality', 'Earth-616')
map.set('education', 'MIT')

const mapIterator = map[Symbol.iterator]()

// Iterate over individual items with next():
mapIterator.next()
// Output:
// { value: [ 'name', 'Tony Stark' ], done: false }

mapIterator.next()
// Output:
// { value: [ 'alias', 'Iron Man' ], done: false }

mapIterator.next()
// Output:
// { value: [ 'reality', 'Earth-616' ], done: false }

mapIterator.next()
// Output:
// { value: [ 'education', 'MIT' ], done: false }


// Iterate over the Map using for...of loop:
for (const [key, value] of map) {
  console.log(`${key}: ${value}`);
}
// Output:
'name: Tony Stark'
'alias: Iron Man'
'reality: Earth-616'
'education: MIT'

Jogos

O quarto e último tipo iterável é o objeto Set . Setobjetos são semelhantes a matrizes. A principal diferença entre a Sete um array é que Setnão permite valores duplicados. Ao tentar adicionar valor duplicado, Setirá manter apenas a primeira ocorrência do valor e ignorar a segunda.

// Create a map and iterator object for it:
const set = new Set(['north', 'east', 'west', 'south'])
const setIterator = set[Symbol.iterator]()

// Iterate over individual items with next():
setIterator.next()
// Output:
// { value: 'north', done: false }

setIterator.next()
// Output:
// { value: 'east', done: false }

setIterator.next()
// Output:
// { value: 'west', done: false }

setIterator.next()
// Output:
// { value: 'south', done: false }


// Iterate over the Set using for...of loop:
for (const item of set) {
  console.log(item);
}
// Output:
'north'
'east'
'west'
'south'

Consumidores iteráveis ​​e trabalhando com tipos iteráveis

Esses são os quatro tipos iteráveis ​​com os quais podemos trabalhar em JavaScript. A próxima pergunta é: como podemos usá-los ou consumi-los. Existem quatro consumidores populares que nos permitem “consumir” iteráveis. Esses consumidores são: for...ofloop, atribuição de desestruturação, operador de propagação e Array.from().

para … de loop

A primeira maneira de iterar sobre iteradores JavaScript é usando o for...ofloop. A desvantagem do for...ofloop é que ele não nos dá muito controle sobre a iteração. No entanto, se tudo o que precisamos é recuperar cada item da coleção, ele fará o trabalho.

// Array:
const numbers = [2, 4, 6]

for (const num of numbers) {
  console.log(num)
}
// Output:
// 2
// 4
// 6


// String:
const word = 'Root'

for (const char of word) {
  console.log(char)
}
// Output:
// 'R'
// 'o'
// 'o'
// 't'


// Map:
const map = new Map([
  ['name', 'Joe'],
  ['age', 33],
])

for (const [key, val] of map) {
  console.log(`${key}: ${val}`)
}
// Output:
// 'name: Joe'
// 'age: 33'


// Set:
const set = new Set(['C++', 'Assembly', 'JavaScript', 'C++'])

for (const language of set) {
  console.log(language)
}
// Output:
// 'C++'
// 'Assembly'
// 'JavaScript'

Atribuição de reestruturação

Uma maneira rápida de recuperar itens de iteradores JavaScript é usando atribuição de desestruturação . Com a desestruturação, podemos recuperar qualquer item de que precisamos, um único item por vez ou vários itens de uma vez.

// Array:
const genres = ['rock', 'hip hop', 'r&b', 'metal', 'soul']

// Destructuring assignment:
const [ first, second, ...rest ] = genres

console.log(first)
// Output:
// 'rock'

console.log(second)
// Output:
// 'hip hop'

console.log(rest)
// Output:
// [ 'r&b', 'metal', 'soul' ]


// String:
const word = 'Recursion'

// Destructuring assignment:
const [first, second, third, ...rest] = word

console.log(first)
// Output:
// 'R'

console.log(second)
// Output:
// 'e'

console.log(third)
// Output:
// 'c'

console.log(rest)
// Output:
// [ 'u', 'r', 's', 'i', 'o', 'n' ]


// Map:
const map = new Map([
  ['water', 'fire'],
  ['white', 'black'],
  ['left', 'right'],
])

// Destructuring assignment:
const [start, middle, end] = map

console.log(start)
// Output:
// [ 'water', 'fire' ]

console.log(middle)
// Output:
// [ 'white', 'black' ]

console.log(end)
// Output:
// [ 'left', 'right' ]


// Set:
const set = new Set([1, 33, 777, 9999])

// Destructuring assignment:
const [ first, second, ...rest ] = set

console.log(first)
// Output:
// 1

console.log(second)
// Output:
// 33

console.log(rest)
// Output:
// [ 777, 9999 ]

Operador Spread

O operador Spread oferece uma maneira rápida e simples de iterar sobre o tipo iterável e transformá-lo em um array. Isso não será útil ao trabalhar com matrizes. Ainda pode ser útil ao lidar com mapas, strings e também conjuntos.

// String:
const word = 'closure'

// Spread:
const wordSpread = [...word]

console.log(wordSpread)
// Output:
// [
//   'c', 'l', 'o',
//   's', 'u', 'r',
//   'e'
// ]


// Map:
const map = new Map([
  ['fruit', 'apple'],
  ['thatGreenThing', 'kale'],
  ['beverage', 'tea']
])

// Spread:
const mapSpread = [...map]

console.log(mapSpread)
// Output:
// [
//   [ 'fruit', 'apple' ],
//   [ 'thatGreenThing', 'kale' ],
//   [ 'beverage', 'tea' ]
// ]


// Set:
const set = new Set(['Halo', 'Quake', 'NFS', 'C&C'])

// Spread:
const setSpread = [...set]

console.log(setSpread)
// Output:
// [ 'Halo', 'Quake', 'NFS', 'C&C' ]

Array.from ()

Junto com o operador de propagação, Array.from()também nos permite transformar qualquer iterável em um array. Tudo o que precisamos fazer é passar o iterável como um argumento para o from()método.

// String:
const word = 'iterable'

// Spread:
const wordArray = Array.from(word)

console.log(wordArray)
// Output:
// [
//   'i', 't', 'e',
//   'r', 'a', 'b',
//   'l', 'e'
// ]


// Map:
const map = new Map([
  [1, 1],
  [2, 10],
  [3, 11],
  [4, 100]
])

// Spread:
const mapArray = Array.from(map)

console.log(mapArray)
// Output:
// [ [ 1, 1 ], [ 2, 10 ], [ 3, 11 ], [ 4, 100 ] ]


// Set:
const set = new Set(['BTC', 'ETH', 'ADA', 'EOS'])

// Spread:
const setArray = [...set]

console.log(setArray)
// Output:
// [ 'BTC', 'ETH', 'ADA', 'EOS' ]

Conclusão: Uma introdução simples aos iteradores JavaScript

Iteradores e iteráveis ​​podem ser úteis quando precisamos de uma coleção sobre a qual possamos iterar de maneira controlada. Neste tutorial, vimos o que são iteradores JavaScript, quais tipos de iteradores estão disponíveis e como trabalhar com eles, usando o for...ofloop, atribuição de desestruturação, operador de propagação e Array.from().

Postado em Blog
Escreva um comentário