From dade2bd878ceb4fbf542ede7c8bd58ec78a631e9 Mon Sep 17 00:00:00 2001 From: marcoarib Date: Thu, 23 Apr 2020 07:48:24 -0300 Subject: [PATCH 01/28] Update article.md --- 1-js/05-data-types/06-iterable/article.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/1-js/05-data-types/06-iterable/article.md b/1-js/05-data-types/06-iterable/article.md index 7f72f5caf..510461089 100644 --- a/1-js/05-data-types/06-iterable/article.md +++ b/1-js/05-data-types/06-iterable/article.md @@ -1,5 +1,7 @@ -# Iterables +# Iteráveis + + *Iterable* objects is a generalization of arrays. That's a concept that allows to make any object useable in a `for..of` loop. From 6d67d5b606502816d5cd95dff2022184e466ecff Mon Sep 17 00:00:00 2001 From: marcoarib Date: Thu, 23 Apr 2020 07:51:39 -0300 Subject: [PATCH 02/28] Update article.md --- 1-js/05-data-types/06-iterable/article.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/1-js/05-data-types/06-iterable/article.md b/1-js/05-data-types/06-iterable/article.md index 510461089..f6907bfda 100644 --- a/1-js/05-data-types/06-iterable/article.md +++ b/1-js/05-data-types/06-iterable/article.md @@ -1,6 +1,10 @@ # Iteráveis +Objetos *iteráveis* são uma generalização dos arrays. Este é um conceito que permite que objetos sejam utilizados laços (*loops*) `for..of`. + +Claro, array são iteráveis. Mas + *Iterable* objects is a generalization of arrays. That's a concept that allows to make any object useable in a `for..of` loop. From 88ce2932d36d57b6cef4be4549a718705394d4ab Mon Sep 17 00:00:00 2001 From: marcoarib Date: Thu, 23 Apr 2020 08:05:34 -0300 Subject: [PATCH 03/28] Update article.md --- 1-js/05-data-types/06-iterable/article.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/1-js/05-data-types/06-iterable/article.md b/1-js/05-data-types/06-iterable/article.md index f6907bfda..5d433f4d4 100644 --- a/1-js/05-data-types/06-iterable/article.md +++ b/1-js/05-data-types/06-iterable/article.md @@ -1,9 +1,11 @@ # Iteráveis -Objetos *iteráveis* são uma generalização dos arrays. Este é um conceito que permite que objetos sejam utilizados laços (*loops*) `for..of`. +Objetos *iteráveis* são uma generalização dos arrays. Este é um conceito que permite que objetos sejam utilizados em laços (*loops*) `for..of`. -Claro, array são iteráveis. Mas +Claro, arrays são iteráveis. Mas existem muitos objetos nativos que também são iteráveis. Strings são outro exemplo de objetos iteráveis. Como veremos à frente, muitos operadores e métodos nativos se relacionam com eles. + +Se um objeto representa uma coleção (list, set) de algo, então `for..of` é um ótimo método para iterar através dele. Veremos como isso funciona. From b843ca3ba68073b9555a5abcec2af7c602cde300 Mon Sep 17 00:00:00 2001 From: marcoarib Date: Thu, 23 Apr 2020 08:55:25 -0300 Subject: [PATCH 04/28] Update article.md --- 1-js/05-data-types/06-iterable/article.md | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/1-js/05-data-types/06-iterable/article.md b/1-js/05-data-types/06-iterable/article.md index 5d433f4d4..6b4e5b518 100644 --- a/1-js/05-data-types/06-iterable/article.md +++ b/1-js/05-data-types/06-iterable/article.md @@ -7,13 +7,18 @@ Claro, arrays são iteráveis. Mas existem muitos objetos nativos que também s Se um objeto representa uma coleção (list, set) de algo, então `for..of` é um ótimo método para iterar através dele. Veremos como isso funciona. +## Symbol.iterator +Podemos compreender facilmente o conceito de objetos iteráveis criando um destes objetos. +Como exemplo, temos um objeto que não é um array, mas pode ser iterado usando `for..of`. +É como um objeto vetor que representa um intervalo de números: -*Iterable* objects is a generalization of arrays. That's a concept that allows to make any object useable in a `for..of` loop. - -Of course, Arrays are iterable. But there are many other built-in objects, that are iterable as well. For instance, Strings are iterable also. As we'll see, many built-in operators and methods rely on them. +```js +let range = { + from: 1, + to: 5 +}; -If an object represents a collection (list, set) of something, then `for..of` is a great syntax to loop over it, so let's see how to make it work. ## Symbol.iterator From f895fe476a843fc491f3bd135550169bbcf71be7 Mon Sep 17 00:00:00 2001 From: marcoarib Date: Thu, 23 Apr 2020 12:08:24 -0300 Subject: [PATCH 05/28] Update article.md --- 1-js/05-data-types/06-iterable/article.md | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/1-js/05-data-types/06-iterable/article.md b/1-js/05-data-types/06-iterable/article.md index 6b4e5b518..90830c9e9 100644 --- a/1-js/05-data-types/06-iterable/article.md +++ b/1-js/05-data-types/06-iterable/article.md @@ -3,13 +3,13 @@ Objetos *iteráveis* são uma generalização dos arrays. Este é um conceito que permite que objetos sejam utilizados em laços (*loops*) `for..of`. -Claro, arrays são iteráveis. Mas existem muitos objetos nativos que também são iteráveis. Strings são outro exemplo de objetos iteráveis. Como veremos à frente, muitos operadores e métodos nativos se relacionam com eles. +Claro, arrays são iteráveis. Mas existem muitos objetos nativos que também são iteráveis. Strings são outro exemplo de objetos iteráveis. Como veremos à frente, muitos operadores e métodos nativos dependem eles. Se um objeto representa uma coleção (list, set) de algo, então `for..of` é um ótimo método para iterar através dele. Veremos como isso funciona. ## Symbol.iterator -Podemos compreender facilmente o conceito de objetos iteráveis criando um destes objetos. +Podemos compreender facilmente o conceito de objetos iteráveis ao criar um destes objetos. Como exemplo, temos um objeto que não é um array, mas pode ser iterado usando `for..of`. É como um objeto vetor que representa um intervalo de números: @@ -19,6 +19,9 @@ let range = { to: 5 }; +// Vamos utilizar o `for..of` no objeto criado: +// for(let num of range) ... num=1,2,3,4,5 +``` ## Symbol.iterator From 517d8c36ccbfb4eb20854dfa299b6f401eb82a4d Mon Sep 17 00:00:00 2001 From: marcoarib Date: Thu, 23 Apr 2020 12:09:27 -0300 Subject: [PATCH 06/28] Update article.md --- 1-js/05-data-types/06-iterable/article.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/1-js/05-data-types/06-iterable/article.md b/1-js/05-data-types/06-iterable/article.md index 90830c9e9..3d26838ed 100644 --- a/1-js/05-data-types/06-iterable/article.md +++ b/1-js/05-data-types/06-iterable/article.md @@ -3,7 +3,7 @@ Objetos *iteráveis* são uma generalização dos arrays. Este é um conceito que permite que objetos sejam utilizados em laços (*loops*) `for..of`. -Claro, arrays são iteráveis. Mas existem muitos objetos nativos que também são iteráveis. Strings são outro exemplo de objetos iteráveis. Como veremos à frente, muitos operadores e métodos nativos dependem eles. +Claro, arrays são iteráveis. Mas existem muitos objetos nativos que também são iteráveis. Strings são outro exemplo de objetos iteráveis. Como veremos à frente, muitos operadores e métodos nativos dependem deles. Se um objeto representa uma coleção (list, set) de algo, então `for..of` é um ótimo método para iterar através dele. Veremos como isso funciona. @@ -11,7 +11,7 @@ Se um objeto representa uma coleção (list, set) de algo, então `for..of` é u Podemos compreender facilmente o conceito de objetos iteráveis ao criar um destes objetos. Como exemplo, temos um objeto que não é um array, mas pode ser iterado usando `for..of`. -É como um objeto vetor que representa um intervalo de números: +É como um objeto *range* que representa um intervalo de números: ```js let range = { @@ -19,7 +19,7 @@ let range = { to: 5 }; -// Vamos utilizar o `for..of` no objeto criado: +// Vamos utilizar o for..of no objeto criado: // for(let num of range) ... num=1,2,3,4,5 ``` From 78213c8c80457f75b8841629ffcc40032d843326 Mon Sep 17 00:00:00 2001 From: marcoarib Date: Fri, 24 Apr 2020 08:30:19 -0300 Subject: [PATCH 07/28] Update article.md --- 1-js/05-data-types/06-iterable/article.md | 43 ++++++++++++++++++----- 1 file changed, 34 insertions(+), 9 deletions(-) diff --git a/1-js/05-data-types/06-iterable/article.md b/1-js/05-data-types/06-iterable/article.md index 3d26838ed..da4938e22 100644 --- a/1-js/05-data-types/06-iterable/article.md +++ b/1-js/05-data-types/06-iterable/article.md @@ -23,25 +23,50 @@ let range = { // for(let num of range) ... num=1,2,3,4,5 ``` +Para tornar o `range` iterável (e portanto permitir que `for..of` funcione) precisamos adicionar ao objeto um método chamado `Symbol.iterator` (um símbolo especial nativo criado para isso). -## Symbol.iterator - -We can easily grasp the concept of iterables by making one of our own. +1. Quando o `for..of` começa, ele chama este método uma vez (ou dispara erros, se o método não for encontrado). O método deve retornar um *iterador* -- um objeto com o método `next`. +2. A seguir, o `for..of` passa a trabalhar *somente com o objeto retornado*. +3. Quando o `for..of` necessita de um novo valor, ele chama o método `next()` no objeto em questão. +4. O resultado do método `next()` precisa ser um formulário `{done: Boolean, value: any}`, onde `done=true` indica que aquela iteração foi finalizada, caso contrário, `value` precisa ser um novo valor. -For instance, we have an object, that is not an array, but looks suitable for `for..of`. +Esta é a implementação completa para o objeto chamado `range`: -Like a `range` object that represents an interval of numbers: - -```js +```js executar let range = { from: 1, to: 5 }; -// We want the for..of to work: -// for(let num of range) ... num=1,2,3,4,5 +// 1. a chamada para o for..of aciona inicialmente o código abaixo +range[Symbol.iterator] = function() { + + // ...ele retorna o objeto iterador: + // 2. Daqui em diante, o for..of trabalha somente com esse iterador, solicitando a ele novos valores + return { + current: this.from, + last: this.to, + + // 3. o método next() é acionado a cada iteração pelo laço for..of + next() { + // 4. ele deve retornar o valor como um objeto {done:.., value :...} + if (this.current <= this.last) { + return { done: false, value: this.current++ }; + } else { + return { done: true }; + } + } + }; +}; + +// agora o for..of funciona! +for (let num of range) { + alert(num); // 1, then 2, 3, 4, 5 +} ``` + + To make the `range` iterable (and thus let `for..of` work) we need to add a method to the object named `Symbol.iterator` (a special built-in symbol just for that). 1. When `for..of` starts, it calls that method once (or errors if not found). The method must return an *iterator* -- an object with the method `next`. From 9ef8682280e3a6110391e7c5b5a7bc3900a2fff2 Mon Sep 17 00:00:00 2001 From: marcoarib Date: Fri, 24 Apr 2020 08:51:53 -0300 Subject: [PATCH 08/28] Update article.md --- 1-js/05-data-types/06-iterable/article.md | 43 +---------------------- 1 file changed, 1 insertion(+), 42 deletions(-) diff --git a/1-js/05-data-types/06-iterable/article.md b/1-js/05-data-types/06-iterable/article.md index da4938e22..ff5c9e91f 100644 --- a/1-js/05-data-types/06-iterable/article.md +++ b/1-js/05-data-types/06-iterable/article.md @@ -65,50 +65,9 @@ for (let num of range) { } ``` +Por favor, observe que o principal recurso dos objetos iteráveis -To make the `range` iterable (and thus let `for..of` work) we need to add a method to the object named `Symbol.iterator` (a special built-in symbol just for that). - -1. When `for..of` starts, it calls that method once (or errors if not found). The method must return an *iterator* -- an object with the method `next`. -2. Onward, `for..of` works *only with that returned object*. -3. When `for..of` wants the next value, it calls `next()` on that object. -4. The result of `next()` must have the form `{done: Boolean, value: any}`, where `done=true` means that the iteration is finished, otherwise `value` must be the new value. - -Here's the full implementation for `range`: - -```js run -let range = { - from: 1, - to: 5 -}; - -// 1. call to for..of initially calls this -range[Symbol.iterator] = function() { - - // ...it returns the iterator object: - // 2. Onward, for..of works only with this iterator, asking it for next values - return { - current: this.from, - last: this.to, - - // 3. next() is called on each iteration by the for..of loop - next() { - // 4. it should return the value as an object {done:.., value :...} - if (this.current <= this.last) { - return { done: false, value: this.current++ }; - } else { - return { done: true }; - } - } - }; -}; - -// now it works! -for (let num of range) { - alert(num); // 1, then 2, 3, 4, 5 -} -``` - Please note the core feature of iterables: an important separation of concerns: - The `range` itself does not have the `next()` method. From 5192c9b698bb7b6de62b20fc75488bb29a00cb2c Mon Sep 17 00:00:00 2001 From: marcoarib Date: Fri, 24 Apr 2020 09:21:45 -0300 Subject: [PATCH 09/28] Update article.md --- 1-js/05-data-types/06-iterable/article.md | 31 +++++++++++++++-------- 1 file changed, 21 insertions(+), 10 deletions(-) diff --git a/1-js/05-data-types/06-iterable/article.md b/1-js/05-data-types/06-iterable/article.md index ff5c9e91f..dade8b733 100644 --- a/1-js/05-data-types/06-iterable/article.md +++ b/1-js/05-data-types/06-iterable/article.md @@ -65,21 +65,18 @@ for (let num of range) { } ``` -Por favor, observe que o principal recurso dos objetos iteráveis +Por favor, observe que o principal recurso dos objetos iteráveis, uma importante separação de conceitos: +- O objeto `range` original não possui o método `next()` +- Ao invés disso, outro objeto chamado "iterador" é criado ao acionar `range[Symbol.iterator]()`, e ele lida com toda a iteração. -Please note the core feature of iterables: an important separation of concerns: +Logo, o objeto "iterador" é um objeto separado do original. -- The `range` itself does not have the `next()` method. -- Instead, another object, a so-called "iterator" is created by the call to `range[Symbol.iterator]()`, and it handles the whole iteration. +Tecnicamente, podemos mesclá-los e usar o próprio objeto `range` de modo a tonar o código mais simples. -So, the iterator object is separate from the object it iterates over. +Desse modo: -Technically, we may merge them and use `range` itself as the iterator to make the code simpler. - -Like this: - -```js run +```js executar let range = { from: 1, to: 5, @@ -103,6 +100,20 @@ for (let num of range) { } ``` +Agora `range[Symbol.iterator]()` retorna o objeto `range` original, ele também possui o método `next()` e `this.current` representa o progresso da iteração neste objeto. Mais sucinto? Sim. Em muitos casos isso é algo bom. + +A desvantagem é que agora é impossível ter dois laços `for..of` executando simultaneamente no objeto: eles compartilharão o estado da iteração porque existe apenas um iterador, ou seja, o próprio objeto. Mas dois laços `for..of` paralelos é algo raro, factível em alguns cenários assíncronos. + +```smart header="Infinite iterators" +Iteradores infinitos são também possíveis. Como exemplo, o `range` se torna infinito pelo uso de `range.to = Infinity`. Também podemos criar um objeto iterável que gera uma sequência infinita de número pseudoaleatórios. Isso pode ser útil. + +Não existe limitação para o método `next`, ele pode retornar mais e mais valores, é algo normal. + +Claro, neste cenário o laço `for..of` seria infinito. Mas sempre podemos pará-lo usando um `break`. + +``` + + Now `range[Symbol.iterator]()` returns the `range` object itself: it has the necessary `next()` method and remembers the current iteration progress in `this.current`. Shorter? Yes. And sometimes that's fine too. The downside is that now it's impossible to have two `for..of` loops running over the object simultaneously: they'll share the iteration state, because there's only one iterator -- the object itself. But two parallel for-ofs is a rare thing, doable with some async scenarios. From 715cb27d9a169410403337fb19e93f770fead989 Mon Sep 17 00:00:00 2001 From: marcoarib Date: Fri, 24 Apr 2020 09:23:44 -0300 Subject: [PATCH 10/28] Update article.md --- 1-js/05-data-types/06-iterable/article.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/1-js/05-data-types/06-iterable/article.md b/1-js/05-data-types/06-iterable/article.md index dade8b733..53872f621 100644 --- a/1-js/05-data-types/06-iterable/article.md +++ b/1-js/05-data-types/06-iterable/article.md @@ -65,7 +65,7 @@ for (let num of range) { } ``` -Por favor, observe que o principal recurso dos objetos iteráveis, uma importante separação de conceitos: +Por favor, observe que o principal recurso dos objetos iteráveis, uma importante separação de conceitos (Separação de conceitos): - O objeto `range` original não possui o método `next()` - Ao invés disso, outro objeto chamado "iterador" é criado ao acionar `range[Symbol.iterator]()`, e ele lida com toda a iteração. From 7adea3597800816f0e9f285d0d322a50cebddeaa Mon Sep 17 00:00:00 2001 From: marcoarib Date: Fri, 24 Apr 2020 09:26:59 -0300 Subject: [PATCH 11/28] Update article.md --- 1-js/05-data-types/06-iterable/article.md | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/1-js/05-data-types/06-iterable/article.md b/1-js/05-data-types/06-iterable/article.md index 53872f621..547cdf550 100644 --- a/1-js/05-data-types/06-iterable/article.md +++ b/1-js/05-data-types/06-iterable/article.md @@ -65,7 +65,7 @@ for (let num of range) { } ``` -Por favor, observe que o principal recurso dos objetos iteráveis, uma importante separação de conceitos (Separação de conceitos): +Por favor, observe o principal recurso dos objetos iteráveis, uma importante separação de conceitos (Separação de conceitos): - O objeto `range` original não possui o método `next()` - Ao invés disso, outro objeto chamado "iterador" é criado ao acionar `range[Symbol.iterator]()`, e ele lida com toda a iteração. @@ -105,7 +105,8 @@ Agora `range[Symbol.iterator]()` retorna o objeto `range` original, ele também A desvantagem é que agora é impossível ter dois laços `for..of` executando simultaneamente no objeto: eles compartilharão o estado da iteração porque existe apenas um iterador, ou seja, o próprio objeto. Mas dois laços `for..of` paralelos é algo raro, factível em alguns cenários assíncronos. ```smart header="Infinite iterators" -Iteradores infinitos são também possíveis. Como exemplo, o `range` se torna infinito pelo uso de `range.to = Infinity`. Também podemos criar um objeto iterável que gera uma sequência infinita de número pseudoaleatórios. Isso pode ser útil. +Iteradores infinitos são também possíveis. Como exemplo, o `range` se torna infinito pelo uso de `range.to = Infinity`. +Também podemos criar um objeto iterável que gera uma sequência infinita de número pseudoaleatórios. Isso pode ser útil. Não existe limitação para o método `next`, ele pode retornar mais e mais valores, é algo normal. @@ -114,6 +115,8 @@ Claro, neste cenário o laço `for..of` seria infinito. Mas sempre podemos pará ``` + + Now `range[Symbol.iterator]()` returns the `range` object itself: it has the necessary `next()` method and remembers the current iteration progress in `this.current`. Shorter? Yes. And sometimes that's fine too. The downside is that now it's impossible to have two `for..of` loops running over the object simultaneously: they'll share the iteration state, because there's only one iterator -- the object itself. But two parallel for-ofs is a rare thing, doable with some async scenarios. From 914d0f3678d261fe08d9433888d172f0bd06d7b3 Mon Sep 17 00:00:00 2001 From: marcoarib Date: Fri, 24 Apr 2020 09:27:58 -0300 Subject: [PATCH 12/28] Update article.md --- 1-js/05-data-types/06-iterable/article.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/1-js/05-data-types/06-iterable/article.md b/1-js/05-data-types/06-iterable/article.md index 547cdf550..12fff3906 100644 --- a/1-js/05-data-types/06-iterable/article.md +++ b/1-js/05-data-types/06-iterable/article.md @@ -105,11 +105,11 @@ Agora `range[Symbol.iterator]()` retorna o objeto `range` original, ele também A desvantagem é que agora é impossível ter dois laços `for..of` executando simultaneamente no objeto: eles compartilharão o estado da iteração porque existe apenas um iterador, ou seja, o próprio objeto. Mas dois laços `for..of` paralelos é algo raro, factível em alguns cenários assíncronos. ```smart header="Infinite iterators" -Iteradores infinitos são também possíveis. Como exemplo, o `range` se torna infinito pelo uso de `range.to = Infinity`. -Também podemos criar um objeto iterável que gera uma sequência infinita de número pseudoaleatórios. Isso pode ser útil. +Iteradores infinitos são possíveis. Como exemplo, o `range` se torna infinito pelo uso de `range.to = Infinity`. +Também podemos criar um objeto iterável que gera uma sequência infinita de número pseudoaleatórios. +Isso pode ser útil. Não existe limitação para o método `next`, ele pode retornar mais e mais valores, é algo normal. - Claro, neste cenário o laço `for..of` seria infinito. Mas sempre podemos pará-lo usando um `break`. ``` From b77d13363e302d2318197a918e8eeed222a85450 Mon Sep 17 00:00:00 2001 From: marcoarib Date: Fri, 24 Apr 2020 09:28:36 -0300 Subject: [PATCH 13/28] Update article.md --- 1-js/05-data-types/06-iterable/article.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/1-js/05-data-types/06-iterable/article.md b/1-js/05-data-types/06-iterable/article.md index 12fff3906..68d6dcb65 100644 --- a/1-js/05-data-types/06-iterable/article.md +++ b/1-js/05-data-types/06-iterable/article.md @@ -106,7 +106,7 @@ A desvantagem é que agora é impossível ter dois laços `for..of` executando s ```smart header="Infinite iterators" Iteradores infinitos são possíveis. Como exemplo, o `range` se torna infinito pelo uso de `range.to = Infinity`. -Também podemos criar um objeto iterável que gera uma sequência infinita de número pseudoaleatórios. +Também podemos criar um objeto iterável que gera uma sequência infinita de números pseudoaleatórios. Isso pode ser útil. Não existe limitação para o método `next`, ele pode retornar mais e mais valores, é algo normal. From 22d766d01d9de8ceca7dd072518d08e7da32ea36 Mon Sep 17 00:00:00 2001 From: marcoarib Date: Sun, 26 Apr 2020 19:33:46 -0300 Subject: [PATCH 14/28] Update article.md --- 1-js/05-data-types/06-iterable/article.md | 51 +++++++++++++---------- 1 file changed, 30 insertions(+), 21 deletions(-) diff --git a/1-js/05-data-types/06-iterable/article.md b/1-js/05-data-types/06-iterable/article.md index 68d6dcb65..6982e61ba 100644 --- a/1-js/05-data-types/06-iterable/article.md +++ b/1-js/05-data-types/06-iterable/article.md @@ -114,43 +114,52 @@ Claro, neste cenário o laço `for..of` seria infinito. Mas sempre podemos pará ``` +## String é iterável +Arrays e Strings são os objetos iteráveis mais comumente usados. +No caso de uma string, um laço `for..of` percorre os seus caracteres: -Now `range[Symbol.iterator]()` returns the `range` object itself: it has the necessary `next()` method and remembers the current iteration progress in `this.current`. Shorter? Yes. And sometimes that's fine too. +```js executar +for (let char of "test") { + // a linha abaixo executa 4 vezes: uma vez para cada caracter + alert( char ); // t, then e, then s, then t +} +``` -The downside is that now it's impossible to have two `for..of` loops running over the object simultaneously: they'll share the iteration state, because there's only one iterator -- the object itself. But two parallel for-ofs is a rare thing, doable with some async scenarios. +E funciona corretamente com caracteres substitutos! -```smart header="Infinite iterators" -Infinite iterators are also possible. For instance, the `range` becomes infinite for `range.to = Infinity`. Or we can make an iterable object that generates an infinite sequence of pseudorandom numbers. Also can be useful. +```js executar +let str = '𝒳😂'; +for (let char of str) { + alert( char ); // 𝒳, and then 😂 +} +``` +## Chamando um iterador explicitamente -There are no limitations on `next`, it can return more and more values, that's normal. +Normalmente, o mecanismo interno dos objetos iteráveis não é visível. O laço `for..of` funciona e isso é tudo o que se precisa saber. -Of course, the `for..of` loop over such an iterable would be endless. But we can always stop it using `break`. -``` +Mas para entender as coisas um pouco mais detalhadamente, vamos ver como criar um iterador explicitamente. +Vamos iterar sobre uma string do mesmo modo que um laço `for..of`, mas com chamadas diretas. O código a seguir cria um iterador para uma string e o chama "manualmente": -## String is iterable +```js executar +let str = "Hello"; -Arrays and strings are most widely used built-in iterables. +// faz o mesmo que +// for (let char of str) alert(char); -For a string, `for..of` loops over its characters: +let iterator = str[Symbol.iterator](); -```js run -for (let char of "test") { - // triggers 4 times: once for each character - alert( char ); // t, then e, then s, then t +while (true) { + let result = iterator.next(); + if (result.done) break; + alert(result.value); // gera os caracteres um por um } ``` -And it works correctly with surrogate pairs! -```js run -let str = '𝒳😂'; -for (let char of str) { - alert( char ); // 𝒳, and then 😂 -} -``` + ## Calling an iterator explicitly From e0741c9ead03d88dac5a2799e55eafd223bd2890 Mon Sep 17 00:00:00 2001 From: marcoarib Date: Sun, 26 Apr 2020 20:13:00 -0300 Subject: [PATCH 15/28] Update article.md --- 1-js/05-data-types/06-iterable/article.md | 93 +++++++++-------------- 1 file changed, 37 insertions(+), 56 deletions(-) diff --git a/1-js/05-data-types/06-iterable/article.md b/1-js/05-data-types/06-iterable/article.md index 6982e61ba..d6cb8c90e 100644 --- a/1-js/05-data-types/06-iterable/article.md +++ b/1-js/05-data-types/06-iterable/article.md @@ -123,7 +123,7 @@ No caso de uma string, um laço `for..of` percorre os seus caracteres: ```js executar for (let char of "test") { // a linha abaixo executa 4 vezes: uma vez para cada caracter - alert( char ); // t, then e, then s, then t + alert( char ); // t, depois e, depois s e por último t } ``` @@ -132,19 +132,19 @@ E funciona corretamente com caracteres substitutos! ```js executar let str = '𝒳😂'; for (let char of str) { - alert( char ); // 𝒳, and then 😂 + alert( char ); // 𝒳, e então 😂 } ``` ## Chamando um iterador explicitamente Normalmente, o mecanismo interno dos objetos iteráveis não é visível. O laço `for..of` funciona e isso é tudo o que se precisa saber. -Mas para entender as coisas um pouco mais detalhadamente, vamos ver como criar um iterador explicitamente. +Mas para entender as coisas um pouco mais detalhadamente, veremos como criar um iterador explicitamente. Vamos iterar sobre uma string do mesmo modo que um laço `for..of`, mas com chamadas diretas. O código a seguir cria um iterador para uma string e o chama "manualmente": ```js executar -let str = "Hello"; +let str = "Olá"; // faz o mesmo que // for (let char of str) alert(char); @@ -154,97 +154,78 @@ let iterator = str[Symbol.iterator](); while (true) { let result = iterator.next(); if (result.done) break; - alert(result.value); // gera os caracteres um por um + alert(result.value); // exibe os caracteres um a um } ``` +Isso é algo raramente utilizado, mas nos dá mais controle sobre o processo do que se estivéssemos utilizando um `for..of`. Como exemplo, podemos dividir o processo de iteração: itere um pouco, então para, faça alguma outra coisa, e então termina mais tarde. +## Iteráveis e array-likes [#array-like] +Estes dois termos oficiais parecem similares, mas são bastante diferentes. Certifique-se de ter os entendido bem para evitar confusão. -## Calling an iterator explicitly +- *Iteráveis* são objetos que implementam o método `Symbol.iterator`, como descrito acima. +- *Array-likes* são objetos que possuem índices e tamanho (`length`), logo, eles se parecem com arrays. -Normally, internals of iterables are hidden from the external code. There's a `for..of` loop, that works, that's all it needs to know. +Naturalmente, essas propriedades podem ser combinadas. Por exemplo, strings são objetos iteráveis (`for..of` funciona com eles) e *array-like* (eles possuem índices e tamanho). -But to understand things a little bit deeper let's see how to create an iterator explicitly. +Mas um iterável pode não ser um *array-like*. Por outro lado, um *array-like* pode não ser um iterável. -We'll iterate over a string the same way as `for..of`, but with direct calls. This code gets a string iterator and calls it "manually": +Por exemplo, o objeto `range` no exemplo acima por ser um iterável, mas não um *array-like*, porque ele não tem propriedades de índice e tamanho (`length`). -```js run -let str = "Hello"; - -// does the same as -// for (let char of str) alert(char); - -let iterator = str[Symbol.iterator](); - -while (true) { - let result = iterator.next(); - if (result.done) break; - alert(result.value); // outputs characters one by one -} -``` - -That is rarely needed, but gives us more control over the process than `for..of`. For instance, we can split the iteration process: iterate a bit, then stop, do something else, and then resume later. - -## Iterables and array-likes [#array-like] - -There are two official terms that look similar, but are very different. Please make sure you understand them well to avoid the confusion. - -- *Iterables* are objects that implement the `Symbol.iterator` method, as described above. -- *Array-likes* are objects that have indexes and `length`, so they look like arrays. - -Naturally, these properties can combine. For instance, strings are both iterable (`for..of` works on them) and array-like (they have numeric indexes and `length`). +Abaixo um exemplo de objeto que é um *array-like*, mas não um iterável: -But an iterable may be not array-like. And vice versa an array-like may be not iterable. - -For example, the `range` in the example above is iterable, but not array-like, because it does not have indexed properties and `length`. - -And here's the object that is array-like, but not iterable: - -```js run -let arrayLike = { // has indexes and length => array-like - 0: "Hello", - 1: "World", +```js executar +let arrayLike = { // possui índices e tamanho => array-like + 0: "Olá", + 1: "Mundo", length: 2 }; *!* -// Error (no Symbol.iterator) +// Erro (nenhum Symbol.iterator) for (let item of arrayLike) {} */!* ``` -What do they have in common? Both iterables and array-likes are usually *not arrays*, they don't have `push`, `pop` etc. That's rather inconvenient if we have such an object and want to work with it as with an array. +O que eles têm em comum? É comum que Iteráveis e *array-likes* não sejam arrays, eles não possuem métodos como `push`, `pop`, etc. Isso é bastante inconveniente quando se deseja que estes objetos trabalhem da mesma forma que um array. ## Array.from -There's a universal method [Array.from](mdn:js/Array/from) that brings them together. It takes an iterable or array-like value and makes a "real" `Array` from it. Then we can call array methods on it. +Existe um método universal que os reúne. Ele pega um iterável ou *array-like* e faz dele um `Array` "real". Assim podemos chamar métodos típicos de um array sobre ele. -For instance: +Por exemplo: -```js run +```js executar let arrayLike = { - 0: "Hello", - 1: "World", + 0: "Olá", + 1: "Mundo", length: 2 }; *!* let arr = Array.from(arrayLike); // (*) */!* -alert(arr.pop()); // World (method works) +alert(arr.pop()); // Mundo (o método funciona) ``` -`Array.from` at the line `(*)` takes the object, examines it for being an iterable or array-like, then makes a new array and copies there all items. +`Array.from` na linha `(*)` pega o objeto, examina o mesmo como um objeto iterável ou *array-like*, então cria um novo array e copia todos os itens para ele. -The same happens for an iterable: +O mesmo acontece com um iterável: ```js -// assuming that range is taken from the example above +// utilizando o objeto "range" que vimos nos primeiros exemplos let arr = Array.from(range); -alert(arr); // 1,2,3,4,5 (array toString conversion works) +alert(arr); // 1,2,3,4,5 (a conversão do array para string funciona) ``` +A sintáxe completa de `Array.from` fornece uma função opcional de "mapeamento": + +```js +Array.from(obj[, mapFn, thisArg]) +``` + + The full syntax for `Array.from` allows to provide an optional "mapping" function: ```js Array.from(obj[, mapFn, thisArg]) From 4492877170cdca251091668d63fc9dc51904e5b2 Mon Sep 17 00:00:00 2001 From: marcoarib Date: Sun, 26 Apr 2020 21:47:03 -0300 Subject: [PATCH 16/28] Update article.md --- 1-js/05-data-types/06-iterable/article.md | 41 +++++++++++++++-------- 1 file changed, 27 insertions(+), 14 deletions(-) diff --git a/1-js/05-data-types/06-iterable/article.md b/1-js/05-data-types/06-iterable/article.md index d6cb8c90e..99dfcbeaa 100644 --- a/1-js/05-data-types/06-iterable/article.md +++ b/1-js/05-data-types/06-iterable/article.md @@ -214,7 +214,7 @@ alert(arr.pop()); // Mundo (o método funciona) O mesmo acontece com um iterável: ```js -// utilizando o objeto "range" que vimos nos primeiros exemplos +// utilizando o objeto "range" dos primeiros exemplos let arr = Array.from(range); alert(arr); // 1,2,3,4,5 (a conversão do array para string funciona) ``` @@ -225,31 +225,25 @@ A sintáxe completa de `Array.from` fornece uma função opcional de "mapeamento Array.from(obj[, mapFn, thisArg]) ``` +O segundo argumento `mapFn` deve ser a função a ser aplicada a cada elemento antes que o mesmo seja adicionado ao array, e `thisArg` permite adicionar o valor `this` a este elemento. -The full syntax for `Array.from` allows to provide an optional "mapping" function: -```js -Array.from(obj[, mapFn, thisArg]) -``` - -The second argument `mapFn` should be the function to apply to each element before adding to the array, and `thisArg` allows to set `this` for it. - -For instance: +Por exemplo: ```js -// assuming that range is taken from the example above +// utilizando o objeto "range" dos primeiros exemplos -// square each number +// quadrado de cada número let arr = Array.from(range, num => num * num); alert(arr); // 1,4,9,16,25 ``` -Here we use `Array.from` to turn a string into an array of characters: +Aqui usamos `Array.from` para transformar uma string em uma matriz de caracteres: -```js run +```js executar let str = '𝒳😂'; -// splits str into array of characters +// divide a string em uma matriz de caracteres let chars = Array.from(str); alert(chars[0]); // 𝒳 @@ -257,6 +251,25 @@ alert(chars[1]); // 😂 alert(chars.length); // 2 ``` +Ao contrário de `str.split`, o código acima se baseia na natureza iterável da string e, assim como um laço `for..of`, funciona corretamente com caracteres substitutos. + +Tecnicamente, acontece conforme o código abaixo: + +```js executar +let str = '𝒳😂'; + +let chars = []; // Array.from internamente executa o mesmo loop +for (let char of str) { + chars.push(char); +} + +alert(chars); +``` + +...Mas + + + Unlike `str.split`, it relies on the iterable nature of the string and so, just like `for..of`, correctly works with surrogate pairs. Technically here it does the same as: From d09624fbfbcd0e2721bc5def399073fad5f2e913 Mon Sep 17 00:00:00 2001 From: marcoarib Date: Sun, 26 Apr 2020 22:07:25 -0300 Subject: [PATCH 17/28] Update article.md --- 1-js/05-data-types/06-iterable/article.md | 55 +++++++---------------- 1 file changed, 17 insertions(+), 38 deletions(-) diff --git a/1-js/05-data-types/06-iterable/article.md b/1-js/05-data-types/06-iterable/article.md index 99dfcbeaa..fdf92ffec 100644 --- a/1-js/05-data-types/06-iterable/article.md +++ b/1-js/05-data-types/06-iterable/article.md @@ -258,7 +258,7 @@ Tecnicamente, acontece conforme o código abaixo: ```js executar let str = '𝒳😂'; -let chars = []; // Array.from internamente executa o mesmo loop +let chars = []; // Array.from internamente executa o mesmo laço for (let char of str) { chars.push(char); } @@ -266,30 +266,11 @@ for (let char of str) { alert(chars); ``` -...Mas +...mas de uma forma mais curta e simples. +Podemos inclusive construir um código que reconheça o caracter substituto: - -Unlike `str.split`, it relies on the iterable nature of the string and so, just like `for..of`, correctly works with surrogate pairs. - -Technically here it does the same as: - -```js run -let str = '𝒳😂'; - -let chars = []; // Array.from internally does the same loop -for (let char of str) { - chars.push(char); -} - -alert(chars); -``` - -...But is shorter. - -We can even build surrogate-aware `slice` on it: - -```js run +```js executar function slice(str, start, end) { return Array.from(str).slice(start, end).join(''); } @@ -298,25 +279,23 @@ let str = '𝒳😂𩷶'; alert( slice(str, 1, 3) ); // 😂𩷶 -// native method does not support surrogate pairs -alert( str.slice(1, 3) ); // garbage (two pieces from different surrogate pairs) +// método nativo não suporta caracteres substitutos +alert( str.slice(1, 3) ); // lixo (duas partes de diferentes caracteres substitutos) ``` +## Sumário -## Summary - -Objects that can be used in `for..of` are called *iterable*. - -- Technically, iterables must implement the method named `Symbol.iterator`. - - The result of `obj[Symbol.iterator]` is called an *iterator*. It handles the further iteration process. - - An iterator must have the method named `next()` that returns an object `{done: Boolean, value: any}`, here `done:true` denotes the iteration end, otherwise the `value` is the next value. -- The `Symbol.iterator` method is called automatically by `for..of`, but we also can do it directly. -- Built-in iterables like strings or arrays, also implement `Symbol.iterator`. -- String iterator knows about surrogate pairs. +Objetos que podem ser usados em um laço `for..of` são chamados de *iteráveis*. +- Tecnicamente, os iteráveis devem implementar o método chamado `Symbol.iterator`. + - O resultado de `obj[Symbol.iterator]` é chamado de *iterador*. Ele lida com o processo de iteração adicional. + - Um iterador deve ter o método chamado `next()` que retorna um objeto `{done: Boolean, value: any}`, aqui `done: true` denota o final da iteração, caso contrário, o `value` é o próximo valor. +- O método `Symbol.iterator` é chamado automaticamente pelo laço `for..of`, mas também podemos fazê-lo diretamente. +- Objetos iteráveis nativos, como strings ou arrays, também implementam o `Symbol.iterator`. +- Um iterador de strings reconhece caracteres substitutos. -Objects that have indexed properties and `length` are called *array-like*. Such objects may also have other properties and methods, but lack the built-in methods of arrays. +Objetos que possuem propriedades índice e tamanho (`length`), são chamados *array-likes*. Esses objetos também podem ter outras propriedades e métodos, mas não possuem os métodos nativos de matrizes. -If we look inside the specification -- we'll see that most built-in methods assume that they work with iterables or array-likes instead of "real" arrays, because that's more abstract. +Se investigarmos mais detalhadamente a especificação -- veremos que a maioria dos métodos nativos assumem que funcionam com objetos iteráveis e *array-likes* ao invés de arrays "reais", porque isso é mais abstrato. -`Array.from(obj[, mapFn, thisArg])` makes a real `Array` of an iterable or array-like `obj`, and we can then use array methods on it. The optional arguments `mapFn` and `thisArg` allow us to apply a function to each item. +`Array.from(obj[, mapFn, thisArg])` cria um array "real" a partir de um objeto iterável ou *array-like*, e consequentemente podemos usar métodos de arrays neles. Os argumentos opcionais `mapFn` e `thisArg` nos permitem aplicar em função a cada item. From d8b77a1fd7bc87afa20afea136368765b7b3e8fe Mon Sep 17 00:00:00 2001 From: marcoarib Date: Sun, 26 Apr 2020 22:20:06 -0300 Subject: [PATCH 18/28] Update article.md --- 1-js/05-data-types/06-iterable/article.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/1-js/05-data-types/06-iterable/article.md b/1-js/05-data-types/06-iterable/article.md index fdf92ffec..b2f26903b 100644 --- a/1-js/05-data-types/06-iterable/article.md +++ b/1-js/05-data-types/06-iterable/article.md @@ -3,7 +3,7 @@ Objetos *iteráveis* são uma generalização dos arrays. Este é um conceito que permite que objetos sejam utilizados em laços (*loops*) `for..of`. -Claro, arrays são iteráveis. Mas existem muitos objetos nativos que também são iteráveis. Strings são outro exemplo de objetos iteráveis. Como veremos à frente, muitos operadores e métodos nativos dependem deles. +Claro, arrays são iteráveis. Mas existem muitos objetos nativos que também são iteráveis. Strings são outro exemplo de objetos iteráveis. Como veremos à frente, muitos operadores e métodos nativos atuam sobre eles. Se um objeto representa uma coleção (list, set) de algo, então `for..of` é um ótimo método para iterar através dele. Veremos como isso funciona. @@ -65,7 +65,7 @@ for (let num of range) { } ``` -Por favor, observe o principal recurso dos objetos iteráveis, uma importante separação de conceitos (Separação de conceitos): +Por favor, observe o principal recurso dos objetos iteráveis, isto é, uma importante separação de conceitos (Separação de conceitos): - O objeto `range` original não possui o método `next()` - Ao invés disso, outro objeto chamado "iterador" é criado ao acionar `range[Symbol.iterator]()`, e ele lida com toda a iteração. @@ -96,7 +96,7 @@ let range = { }; for (let num of range) { - alert(num); // 1, then 2, 3, 4, 5 + alert(num); // 1, e depois 2, 3, 4, 5 } ``` @@ -114,7 +114,7 @@ Claro, neste cenário o laço `for..of` seria infinito. Mas sempre podemos pará ``` -## String é iterável +## Strings são iteráveis Arrays e Strings são os objetos iteráveis mais comumente usados. @@ -132,7 +132,7 @@ E funciona corretamente com caracteres substitutos! ```js executar let str = '𝒳😂'; for (let char of str) { - alert( char ); // 𝒳, e então 😂 + alert( char ); // 𝒳, e depois 😂 } ``` ## Chamando um iterador explicitamente @@ -158,7 +158,7 @@ while (true) { } ``` -Isso é algo raramente utilizado, mas nos dá mais controle sobre o processo do que se estivéssemos utilizando um `for..of`. Como exemplo, podemos dividir o processo de iteração: itere um pouco, então para, faça alguma outra coisa, e então termina mais tarde. +Isso é algo raramente utilizado, mas nos dá mais controle sobre o processo do que se estivéssemos utilizando um `for..of`. Como exemplo, podemos dividir o processo de iteração: itere um pouco, então pare, faça alguma outra coisa, e então termine mais tarde. ## Iteráveis e array-likes [#array-like] @@ -169,7 +169,7 @@ Estes dois termos oficiais parecem similares, mas são bastante diferentes. Cert Naturalmente, essas propriedades podem ser combinadas. Por exemplo, strings são objetos iteráveis (`for..of` funciona com eles) e *array-like* (eles possuem índices e tamanho). -Mas um iterável pode não ser um *array-like*. Por outro lado, um *array-like* pode não ser um iterável. +Mas um iterável pode não ser um *array-like*. Do mesmo modo, um *array-like* pode não ser um iterável. Por exemplo, o objeto `range` no exemplo acima por ser um iterável, mas não um *array-like*, porque ele não tem propriedades de índice e tamanho (`length`). @@ -192,7 +192,7 @@ O que eles têm em comum? É comum que Iteráveis e *array-likes* não sejam arr ## Array.from -Existe um método universal que os reúne. Ele pega um iterável ou *array-like* e faz dele um `Array` "real". Assim podemos chamar métodos típicos de um array sobre ele. +Existe um método universal que os reúne. Ele pega um iterável ou *array-like* e faz dele um `Array` "real". Assim podemos chamar métodos típicos de um array a partir deste objeto. Por exemplo: @@ -232,7 +232,7 @@ Por exemplo: ```js // utilizando o objeto "range" dos primeiros exemplos -// quadrado de cada número +// calcula o quadrado de cada número let arr = Array.from(range, num => num * num); alert(arr); // 1,4,9,16,25 From b856cfbfa3df4c1fec599da9f1627eeb1b40dd81 Mon Sep 17 00:00:00 2001 From: marcoarib Date: Sun, 26 Apr 2020 22:21:24 -0300 Subject: [PATCH 19/28] Update article.md --- 1-js/05-data-types/06-iterable/article.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/1-js/05-data-types/06-iterable/article.md b/1-js/05-data-types/06-iterable/article.md index b2f26903b..02829e61e 100644 --- a/1-js/05-data-types/06-iterable/article.md +++ b/1-js/05-data-types/06-iterable/article.md @@ -294,7 +294,7 @@ Objetos que podem ser usados em um laço `for..of` são chamados de *iteráveis* - Objetos iteráveis nativos, como strings ou arrays, também implementam o `Symbol.iterator`. - Um iterador de strings reconhece caracteres substitutos. -Objetos que possuem propriedades índice e tamanho (`length`), são chamados *array-likes*. Esses objetos também podem ter outras propriedades e métodos, mas não possuem os métodos nativos de matrizes. +Objetos que possuem propriedades índice e tamanho (`length`), são chamados *array-likes*. Esses objetos também podem ter outras propriedades e métodos, mas não possuem os métodos nativos de arrays. Se investigarmos mais detalhadamente a especificação -- veremos que a maioria dos métodos nativos assumem que funcionam com objetos iteráveis e *array-likes* ao invés de arrays "reais", porque isso é mais abstrato. From 3aab5778e570740977ccc3907f5dec0c0181be04 Mon Sep 17 00:00:00 2001 From: marcoarib Date: Sun, 26 Apr 2020 22:22:05 -0300 Subject: [PATCH 20/28] Update article.md --- 1-js/05-data-types/06-iterable/article.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/1-js/05-data-types/06-iterable/article.md b/1-js/05-data-types/06-iterable/article.md index 02829e61e..1e4ad77db 100644 --- a/1-js/05-data-types/06-iterable/article.md +++ b/1-js/05-data-types/06-iterable/article.md @@ -298,4 +298,4 @@ Objetos que possuem propriedades índice e tamanho (`length`), são chamados *ar Se investigarmos mais detalhadamente a especificação -- veremos que a maioria dos métodos nativos assumem que funcionam com objetos iteráveis e *array-likes* ao invés de arrays "reais", porque isso é mais abstrato. -`Array.from(obj[, mapFn, thisArg])` cria um array "real" a partir de um objeto iterável ou *array-like*, e consequentemente podemos usar métodos de arrays neles. Os argumentos opcionais `mapFn` e `thisArg` nos permitem aplicar em função a cada item. +`Array.from(obj[, mapFn, thisArg])` cria um array "real" a partir de um objeto iterável ou *array-like* e, consequentemente, podemos usar métodos de arrays neles. Os argumentos opcionais `mapFn` e `thisArg` nos permitem aplicar em função a cada item. From 251c3d15759cbcd469f646ae9013954bc3172be2 Mon Sep 17 00:00:00 2001 From: marcoarib Date: Sun, 26 Apr 2020 22:22:36 -0300 Subject: [PATCH 21/28] Update article.md --- 1-js/05-data-types/06-iterable/article.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/1-js/05-data-types/06-iterable/article.md b/1-js/05-data-types/06-iterable/article.md index 1e4ad77db..37341fd05 100644 --- a/1-js/05-data-types/06-iterable/article.md +++ b/1-js/05-data-types/06-iterable/article.md @@ -298,4 +298,4 @@ Objetos que possuem propriedades índice e tamanho (`length`), são chamados *ar Se investigarmos mais detalhadamente a especificação -- veremos que a maioria dos métodos nativos assumem que funcionam com objetos iteráveis e *array-likes* ao invés de arrays "reais", porque isso é mais abstrato. -`Array.from(obj[, mapFn, thisArg])` cria um array "real" a partir de um objeto iterável ou *array-like* e, consequentemente, podemos usar métodos de arrays neles. Os argumentos opcionais `mapFn` e `thisArg` nos permitem aplicar em função a cada item. +`Array.from(obj[, mapFn, thisArg])` cria um array "real" a partir de um objeto iterável ou *array-like* e, consequentemente, podemos usar métodos de arrays neles. Os argumentos opcionais `mapFn` e `thisArg` nos permitem aplicar a função em cada item. From 565b3ea9a6886fc006794b4aafafa7467fbf0f07 Mon Sep 17 00:00:00 2001 From: marcoarib Date: Mon, 27 Apr 2020 08:36:55 -0300 Subject: [PATCH 22/28] Update article.md --- 1-js/05-data-types/08-keys-values-entries/article.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/1-js/05-data-types/08-keys-values-entries/article.md b/1-js/05-data-types/08-keys-values-entries/article.md index 66ca3ca92..beb76b955 100644 --- a/1-js/05-data-types/08-keys-values-entries/article.md +++ b/1-js/05-data-types/08-keys-values-entries/article.md @@ -1,3 +1,7 @@ +# Object.keys, valores e entradas + +Vamos dar um passo à frente em relação às estruturas individuais de dados e falaremos sobre as iterações sobre eles. + # Object.keys, values, entries From dc3d009d7e312857c83005e5e904301d4ee7d9fb Mon Sep 17 00:00:00 2001 From: marcoarib Date: Mon, 27 Apr 2020 12:10:45 -0300 Subject: [PATCH 23/28] Update article.md --- .../08-keys-values-entries/article.md | 33 +++++++++---------- 1 file changed, 15 insertions(+), 18 deletions(-) diff --git a/1-js/05-data-types/08-keys-values-entries/article.md b/1-js/05-data-types/08-keys-values-entries/article.md index beb76b955..5563f1261 100644 --- a/1-js/05-data-types/08-keys-values-entries/article.md +++ b/1-js/05-data-types/08-keys-values-entries/article.md @@ -1,38 +1,35 @@ # Object.keys, valores e entradas -Vamos dar um passo à frente em relação às estruturas individuais de dados e falaremos sobre as iterações sobre eles. +Vamos dar um passo à frente em relação às estruturas individuais de dados e falaremos sobre as iterações sobre elas. +No capítulo anterior vimos os métodos `map.keys()`, `map.values()`, `map.entries()`. -# Object.keys, values, entries +Estes métodos são genéricos. Existe um acordo comum para utilizá-los em estruturas de dados. Se criarmos uma estrutura de dados por nós mesmos, deveremos implementar os referidos métodos. -Let's step away from the individual data structures and talk about the iterations over them. - -In the previous chapter we saw methods `map.keys()`, `map.values()`, `map.entries()`. - -These methods are generic, there is a common agreement to use them for data structures. If we ever create a data structure of our own, we should implement them too. - -They are supported for: +Eles são suportados para: - `Map` - `Set` - `Array` (except `arr.values()`) -Plain objects also support similar methods, but the syntax is a bit different. +Objetos simples também suportam métodos semelhantes, mas a sintaxe é um pouco diferente. -## Object.keys, values, entries +## Object.keys, valores e entradas -For plain objects, the following methods are available: +Para objetos simples, os métodos a seguir estão disponíveis: -- [Object.keys(obj)](mdn:js/Object/keys) -- returns an array of keys. -- [Object.values(obj)](mdn:js/Object/values) -- returns an array of values. -- [Object.entries(obj)](mdn:js/Object/entries) -- returns an array of `[key, value]` pairs. +- [Object.keys(obj)](mdn:js/Object/keys) -- retorna um array de chaves. +- [Object.values(obj)](mdn:js/Object/values) -- retorna um array de valores. +- [Object.entries(obj)](mdn:js/Object/entries) -- retorna um array de pares `[chave, valor]`. -...But please note the distinctions (compared to map for example): +...mas observe as distinções (em comparação com o *map*, por exemplo): | | Map | Object | |-------------|------------------|--------------| -| Call syntax | `map.keys()` | `Object.keys(obj)`, but not `obj.keys()` | -| Returns | iterable | "real" Array | +| Sintáxe | `map.keys()` | `Object.keys(obj)`, but not `obj.keys()` | +| Retorno | iterável | Array real + + The first difference is that we have to call `Object.keys(obj)`, and not `obj.keys()`. From 7fa985cb93b8c4417fbd105e2989abf70315681a Mon Sep 17 00:00:00 2001 From: marcoarib Date: Mon, 27 Apr 2020 19:13:59 -0300 Subject: [PATCH 24/28] Update article.md --- .../08-keys-values-entries/article.md | 36 +++++++++---------- 1 file changed, 17 insertions(+), 19 deletions(-) diff --git a/1-js/05-data-types/08-keys-values-entries/article.md b/1-js/05-data-types/08-keys-values-entries/article.md index 5563f1261..dbbf5e109 100644 --- a/1-js/05-data-types/08-keys-values-entries/article.md +++ b/1-js/05-data-types/08-keys-values-entries/article.md @@ -29,43 +29,41 @@ Para objetos simples, os métodos a seguir estão disponíveis: | Sintáxe | `map.keys()` | `Object.keys(obj)`, but not `obj.keys()` | | Retorno | iterável | Array real +A primeira diferença é que temos que chamar `Object.keys(obj)` e não `obj.keys()`. +Por que? A principal razão é flexibilidade. Lembre-se, objetos são a base de todas as estruturas complexas no JavaScript. Portanto, podemos ter um objeto como `order`, que implementa seu próprio método `order.values()`. E ainda podemos chamar `Object.values (order)` nele. -The first difference is that we have to call `Object.keys(obj)`, and not `obj.keys()`. +A segunda diferença é que os métodos `Object.*` retornam objetos de arrays "reais", não apenas iteráveis. Isso é principalmente por razões históricas. -Why so? The main reason is flexibility. Remember, objects are a base of all complex structures in JavaScript. So we may have an object of our own like `order` that implements its own `order.values()` method. And we still can call `Object.values(order)` on it. - -The second difference is that `Object.*` methods return "real" array objects, not just an iterable. That's mainly for historical reasons. - -For instance: +Por exemplo: ```js let user = { - name: "John", - age: 30 + nome: "John", + idade: 30 }; ``` -- `Object.keys(user) = ["name", "age"]` +- `Object.keys(user) = ["nome", "age"]` - `Object.values(user) = ["John", 30]` -- `Object.entries(user) = [ ["name","John"], ["age",30] ]` +- `Object.entries(user) = [ ["nome","John"], ["idade",30] ]` -Here's an example of using `Object.values` to loop over property values: +Aqui está um exemplo do uso de `Object.values` para fazer um *loop* sobre os valores da propriedade: -```js run +```js executar let user = { - name: "John", - age: 30 + nome: "John", + idade: 30 }; -// loop over values +// loop sobre os valores for (let value of Object.values(user)) { - alert(value); // John, then 30 + alert(value); // John, e depois 30 } ``` -## Object.keys/values/entries ignore symbolic properties +## Object.keys/valores/entradas ignora propriedades simbólicas -Just like a `for..in` loop, these methods ignore properties that use `Symbol(...)` as keys. +Assim como um laço `for..in`, esses métodos ignoram propriedades que usam `Symbol(...)` como chaves. -Usually that's convenient. But if we want symbolic keys too, then there's a separate method [Object.getOwnPropertySymbols](mdn:js/Object/getOwnPropertySymbols) that returns an array of only symbolic keys. Also, the method [Reflect.ownKeys(obj)](mdn:js/Reflect/ownKeys) returns *all* keys. +Geralmente isso é conveniente. Mas se também queremos chaves simbólicas, existe um método separado [Object.getOwnPropertySymbols] (mdn:js/Object/getOwnPropertySymbols) que retorna um array com chaves simbólicas apenas. Além disso, o método [Reflect.ownKeys (obj)] (mdn:js/Reflect/ownKeys) retorna *todas* as chaves. From d1c58b921805949a19b59468dfd97870bb62a688 Mon Sep 17 00:00:00 2001 From: marcoarib Date: Mon, 27 Apr 2020 19:18:38 -0300 Subject: [PATCH 25/28] Update article.md --- 1-js/05-data-types/08-keys-values-entries/article.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/1-js/05-data-types/08-keys-values-entries/article.md b/1-js/05-data-types/08-keys-values-entries/article.md index dbbf5e109..013e3cc2d 100644 --- a/1-js/05-data-types/08-keys-values-entries/article.md +++ b/1-js/05-data-types/08-keys-values-entries/article.md @@ -10,7 +10,7 @@ Eles são suportados para: - `Map` - `Set` -- `Array` (except `arr.values()`) +- `Array` (exceto `arr.values()`) Objetos simples também suportam métodos semelhantes, mas a sintaxe é um pouco diferente. @@ -26,14 +26,14 @@ Para objetos simples, os métodos a seguir estão disponíveis: | | Map | Object | |-------------|------------------|--------------| -| Sintáxe | `map.keys()` | `Object.keys(obj)`, but not `obj.keys()` | +| Sintáxe | `map.keys()` | `Object.keys(obj)`, mas não `obj.keys()` | | Retorno | iterável | Array real A primeira diferença é que temos que chamar `Object.keys(obj)` e não `obj.keys()`. Por que? A principal razão é flexibilidade. Lembre-se, objetos são a base de todas as estruturas complexas no JavaScript. Portanto, podemos ter um objeto como `order`, que implementa seu próprio método `order.values()`. E ainda podemos chamar `Object.values (order)` nele. -A segunda diferença é que os métodos `Object.*` retornam objetos de arrays "reais", não apenas iteráveis. Isso é principalmente por razões históricas. +A segunda diferença é que os métodos `Object.*` retornam objetos de arrays "reais", não apenas iteráveis. Isso acontece principalmente por razões históricas. Por exemplo: @@ -44,11 +44,11 @@ let user = { }; ``` -- `Object.keys(user) = ["nome", "age"]` +- `Object.keys(user) = ["nome", "idade"]` - `Object.values(user) = ["John", 30]` - `Object.entries(user) = [ ["nome","John"], ["idade",30] ]` -Aqui está um exemplo do uso de `Object.values` para fazer um *loop* sobre os valores da propriedade: +Aqui está um exemplo do uso de `Object.values` para fazer um laço (*loop*) sobre os valores da propriedade: ```js executar let user = { From cbcbae6209f218522e6c3bc7df5388ed68ba57c6 Mon Sep 17 00:00:00 2001 From: marcoarib Date: Sat, 9 May 2020 19:24:56 -0300 Subject: [PATCH 26/28] Update article.md --- 1-js/05-data-types/08-keys-values-entries/article.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/1-js/05-data-types/08-keys-values-entries/article.md b/1-js/05-data-types/08-keys-values-entries/article.md index 013e3cc2d..d1768d08a 100644 --- a/1-js/05-data-types/08-keys-values-entries/article.md +++ b/1-js/05-data-types/08-keys-values-entries/article.md @@ -62,8 +62,8 @@ for (let value of Object.values(user)) { } ``` -## Object.keys/valores/entradas ignora propriedades simbólicas +```warn header="Object.keys/values/entries ignore symbolic properties" +Just like a `for..in` loop, these methods ignore properties that use `Symbol(...)` as keys. -Assim como um laço `for..in`, esses métodos ignoram propriedades que usam `Symbol(...)` como chaves. - -Geralmente isso é conveniente. Mas se também queremos chaves simbólicas, existe um método separado [Object.getOwnPropertySymbols] (mdn:js/Object/getOwnPropertySymbols) que retorna um array com chaves simbólicas apenas. Além disso, o método [Reflect.ownKeys (obj)] (mdn:js/Reflect/ownKeys) retorna *todas* as chaves. +Usually that's convenient. But if we want symbolic keys too, then there's a separate method [Object.getOwnPropertySymbols](mdn:js/Object/getOwnPropertySymbols) that returns an array of only symbolic keys. Also, there exist a method [Reflect.ownKeys(obj)](mdn:js/Reflect/ownKeys) that returns *all* keys. +``` From 8f763f1423cdab67185133c5d44e30068061a7c3 Mon Sep 17 00:00:00 2001 From: marcoarib Date: Sat, 9 May 2020 19:25:15 -0300 Subject: [PATCH 27/28] Update article.md --- .../08-keys-values-entries/article.md | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/1-js/05-data-types/08-keys-values-entries/article.md b/1-js/05-data-types/08-keys-values-entries/article.md index d1768d08a..1e3536ddf 100644 --- a/1-js/05-data-types/08-keys-values-entries/article.md +++ b/1-js/05-data-types/08-keys-values-entries/article.md @@ -67,3 +67,35 @@ Just like a `for..in` loop, these methods ignore properties that use `Symbol(... Usually that's convenient. But if we want symbolic keys too, then there's a separate method [Object.getOwnPropertySymbols](mdn:js/Object/getOwnPropertySymbols) that returns an array of only symbolic keys. Also, there exist a method [Reflect.ownKeys(obj)](mdn:js/Reflect/ownKeys) that returns *all* keys. ``` + + +## Transforming objects + +Objects lack many methods that exist for arrays, e.g. `map`, `filter` and others. + +If we'd like to apply them, then we can use `Object.entries` followed `Object.fromEntries`: + +1. Use `Object.entries(obj)` to get an array of key/value pairs from `obj`. +2. Use array methods on that array, e.g. `map`. +3. Use `Object.fromEntries(array)` on the resulting array to turn it back into an object. + +For example, we have an object with prices, and would like to double them: + +```js run +let prices = { + banana: 1, + orange: 2, + meat: 4, +}; + +*!* +let doublePrices = Object.fromEntries( + // convert to array, map, and then fromEntries gives back the object + Object.entries(prices).map(([key, value]) => [key, value * 2]) +); +*/!* + +alert(doublePrices.meat); // 8 +``` + +It may look difficult from the first sight, but becomes easy to understand after you use it once or twice. We can make powerful chains of transforms this way. From 78c281c76b6a7c4316946a8758065d6a0f076bc2 Mon Sep 17 00:00:00 2001 From: marcoarib Date: Sat, 9 May 2020 19:44:36 -0300 Subject: [PATCH 28/28] Update article.md --- .../08-keys-values-entries/article.md | 35 +++++++++---------- 1 file changed, 17 insertions(+), 18 deletions(-) diff --git a/1-js/05-data-types/08-keys-values-entries/article.md b/1-js/05-data-types/08-keys-values-entries/article.md index 1e3536ddf..42d5911d6 100644 --- a/1-js/05-data-types/08-keys-values-entries/article.md +++ b/1-js/05-data-types/08-keys-values-entries/article.md @@ -62,40 +62,39 @@ for (let value of Object.values(user)) { } ``` -```warn header="Object.keys/values/entries ignore symbolic properties" -Just like a `for..in` loop, these methods ignore properties that use `Symbol(...)` as keys. +```warn header="Object.keys/valores/entradas ignoram propriedades simbólicas" +Assim como um laço `for..in`, estes métodos ignoram propriedades que usam `Symbol(...)` como chaves. -Usually that's convenient. But if we want symbolic keys too, then there's a separate method [Object.getOwnPropertySymbols](mdn:js/Object/getOwnPropertySymbols) that returns an array of only symbolic keys. Also, there exist a method [Reflect.ownKeys(obj)](mdn:js/Reflect/ownKeys) that returns *all* keys. +Usualmente isso é conveniente. Mas se queremos também chaves simbólicas, há um método separado: [Object.getOwnPropertySymbols] (mdn:js/Object/getOwnPropertySymbols) que retorna um array de chaves simbólicas. Além disso, existe um método [Reflect.ownKeys(obj)](mdn:js/Reflect/ownKeys) que retorna *todas* as chaves. ``` +## Transformando objetos -## Transforming objects +Objetos não possuem muitos métodos que estão disponíveis para arrays como, por exemplo, `map`, `filter` e outros. -Objects lack many methods that exist for arrays, e.g. `map`, `filter` and others. +Se quisermos aplicar estes métodos, podemos usar `Object.entries` seguido de `Object.fromEntries`: -If we'd like to apply them, then we can use `Object.entries` followed `Object.fromEntries`: +1. Use `Object.entries(obj)` para obter um array de pares chave/valor a partir de `obj`. +2. Use os métodos de arrays neste array como, por exemplo, `map`. +3. Use `Object.fromEntries(array)` no array resultante para torná-lo um objeto novamente. -1. Use `Object.entries(obj)` to get an array of key/value pairs from `obj`. -2. Use array methods on that array, e.g. `map`. -3. Use `Object.fromEntries(array)` on the resulting array to turn it back into an object. +Por exemplo, temos um objeto com preços e gostaríamos de dobrar os mesmos: -For example, we have an object with prices, and would like to double them: - -```js run +```js executar let prices = { banana: 1, - orange: 2, - meat: 4, + laranja: 2, + carne: 4, }; *!* let doublePrices = Object.fromEntries( - // convert to array, map, and then fromEntries gives back the object + // convert para array, map, e então fromEntries retorna o objeto novamente Object.entries(prices).map(([key, value]) => [key, value * 2]) ); */!* -alert(doublePrices.meat); // 8 -``` +alert(doublePrices.carne); // 8 +``` -It may look difficult from the first sight, but becomes easy to understand after you use it once or twice. We can make powerful chains of transforms this way. +Pode parecer difícil à primeira vista, mas fica fácil de entender depois de você usá-lo uma ou duas vezes. Podemos fazer cadeias poderosas de transformações dessa maneira.