Skip to content

Commit ea67503

Browse files
Merge pull request #179 from vplentinax/iterable
Iterables
2 parents dc48bfc + 36b0d08 commit ea67503

File tree

1 file changed

+102
-99
lines changed

1 file changed

+102
-99
lines changed
Lines changed: 102 additions & 99 deletions
Original file line numberDiff line numberDiff line change
@@ -1,58 +1,58 @@
11

22
# Iterables
33

4-
*Iterable* objects is a generalization of arrays. That's a concept that allows us to make any object useable in a `for..of` loop.
4+
Los objetos *iterables* son una generalización de matrices. Este es un concepto que permite que cualquier objeto pueda ser utilizado en un blucle `for..of`.
55

6-
Of course, Arrays are iterable. But there are many other built-in objects, that are iterable as well. For instance, strings are also iterable.
7-
8-
If an object isn't technically an array, but 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.
6+
Por supuesto, las matrices o *arrays* son iterables. Pero hay muchos otros objetos integrados, que también lo son. Por ejemplo, las cadenas o *strings* son iterables también. Como veremos, muchos operadores y métodos se basan en la iterabilidad.
97

8+
Si un objeto no es técnicamente una matriz, pero representa una colección (lista, conjunto) de algo, entonces el uso de la sintaxis `for..of` es una gran forma de recorrerlo, así que veamos cómo funciona.
109

1110
## Symbol.iterator
1211

13-
We can easily grasp the concept of iterables by making one of our own.
12+
Podemos comprender fácilmente el concepto de iterables por medio de la práctica.
13+
14+
Por ejemplo, tenemos un objeto, que no es una matriz, pero parece adecuado para `for..of`.
1415

15-
For instance, we have an object that is not an array, but looks suitable for `for..of`.
1616

17-
Like a `range` object that represents an interval of numbers:
17+
Como un objeto `range` que representa un intervalo de números:
1818

1919
```js
2020
let range = {
2121
from: 1,
2222
to: 5
2323
};
2424

25-
// We want the for..of to work:
25+
// Queremos que el for..of funcione de la siguiente manera:
2626
// for(let num of range) ... num=1,2,3,4,5
2727
```
2828

29-
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).
30-
31-
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`.
32-
2. Onward, `for..of` works *only with that returned object*.
33-
3. When `for..of` wants the next value, it calls `next()` on that object.
34-
4. The result of `next()` must have the form `{done: Boolean, value: any}`, where `done=true` means that the iteration is finished, otherwise `value` is the next value.
29+
Para hacer que el `range` sea iterable (y así permitir que `for..of` funcione) necesitamos agregar un método al objeto llamado `Symbol.iterator` (un símbolo incorporado especial usado solo para realizar esa función, proporcionar iterabilidad).
3530

36-
Here's the full implementation for `range` with remarks:
31+
1. Cuando se inicia el `for..of`, éste llama al método `Symbol.iterator` una vez (o genera un error si no lo encuentra). El método debe devolver un *iterador* --un objeto con el método `next()`.
32+
2. En adelante, `for..of` trabaja *solo con ese objeto devuelto*.
33+
3. Cuando `for..of` quiere el siguiente valor, llama a `next()` en ese objeto.
34+
4.El resultado de `next()` debe tener la forma `{done: Boolean, value: any}`, donde `done = true` significa que la iteración ha finalizado; de lo contrario,`value` debe ser el nuevo valor.
3735

36+
Aquí está la implementación completa de `range`:
37+
 
3838
```js run
3939
let range = {
4040
from: 1,
4141
to: 5
4242
};
4343

44-
// 1. call to for..of initially calls this
44+
// 1. Una llamada a for..of inicializa una llamada a esto:
4545
range[Symbol.iterator] = function() {
4646

47-
// ...it returns the iterator object:
48-
// 2. Onward, for..of works only with this iterator, asking it for next values
47+
// ... devuelve el objeto iterador:
48+
// 2. En adelante, for..of trabaja solo con este iterador, pidiéndole los siguientes valores
4949
return {
5050
current: this.from,
5151
last: this.to,
5252

53-
// 3. next() is called on each iteration by the for..of loop
53+
// 3. next() es llamado en cada iteración por el bucle for..of
5454
next() {
55-
// 4. it should return the value as an object {done:.., value :...}
55+
// 4. debería devolver el valor como un objeto {done:.., value :...}
5656
if (this.current <= this.last) {
5757
return { done: false, value: this.current++ };
5858
} else {
@@ -62,22 +62,22 @@ range[Symbol.iterator] = function() {
6262
};
6363
};
6464

65-
// now it works!
65+
// ¡Ahora funciona!
6666
for (let num of range) {
6767
alert(num); // 1, then 2, 3, 4, 5
6868
}
6969
```
7070

71-
Please note the core feature of iterables: separation of concerns.
71+
Tenga en cuenta la característica principal de los iterables: separación de conceptos.
7272

73-
- The `range` itself does not have the `next()` method.
74-
- Instead, another object, a so-called "iterator" is created by the call to `range[Symbol.iterator]()`, and its `next()` generates values for the iteration.
73+
- El `range` en sí mismo no tiene el método `next()`.
74+
- En cambio, la llamada a `range[Symbol.iterator]()` crea un otro objeto llamado "iterador", y su `next()` genera valores para la iteración.
7575

76-
So, the iterator object is separate from the object it iterates over.
76+
Por lo tanto, el objeto iterador está separado del objeto sobre el que itera.
7777

78-
Technically, we may merge them and use `range` itself as the iterator to make the code simpler.
78+
Técnicamente, podemos fusionarlos y usar `range` en sí mismo como iterador para simplificar el código.
7979

80-
Like this:
80+
De esta manera:
8181

8282
```js run
8383
let range = {
@@ -103,51 +103,51 @@ for (let num of range) {
103103
}
104104
```
105105

106-
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.
106+
Ahora `range[Symbol.iterator]()` devuelve el objeto `range` en sí: tiene el método `next()` necesario y recuerda el progreso de iteración actual en `this.current`. ¿Más corto? Sí. Y a veces eso también está bien.
107107

108-
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, even in async scenarios.
108+
La desventaja es que ahora es imposible tener dos bucles `for..of` corriendo sobre el objeto simultáneamente: compartirán el estado de iteración, porque solo hay un iterador: el objeto en sí. Pero dos for-ofs paralelos es algo raro, incluso en escenarios asíncronos.
109+
 
110+
```smart header="Iteradores Infinitos"
111+
También son posibles los iteradores infinitos. Por ejemplo, el objeto `range` se vuelve infinito así: `range.to = Infinity`. O podemos hacer un objeto iterable que genere una secuencia infinita de números pseudoaleatorios. También puede ser útil.
109112
110-
```smart header="Infinite iterators"
111-
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.
113+
No hay limitaciones en `next`, puede devolver más y más valores, eso es normal.
112114
113-
There are no limitations on `next`, it can return more and more values, that's normal.
114-
115-
Of course, the `for..of` loop over such an iterable would be endless. But we can always stop it using `break`.
115+
Por supuesto, el bucle `for..of` sobre un iterable de este tipo sería interminable. Pero siempre podemos detenerlo usando `break`.
116116
```
117117

118+
## *String* es iterable
118119

119-
## String is iterable
120-
121-
Arrays and strings are most widely used built-in iterables.
120+
Las matrices y cadenas son los iterables integrados más utilizados.
122121

123-
For a string, `for..of` loops over its characters:
122+
En una cadena o *string*, el bucle `for..of` recorre sus caracteres:
124123

125124
```js run
126125
for (let char of "test") {
127-
// triggers 4 times: once for each character
128-
alert( char ); // t, then e, then s, then t
126+
// Se dispara 4 veces: una vez por cada caracter
127+
alert( char ); // t, luego e, luego s, luego t
129128
}
130129
```
131130

132-
And it works correctly with surrogate pairs!
131+
¡Y trabaja correctamente con valores de pares sustitutos (codificación UTF-16)!
133132

134133
```js run
135134
let str = '𝒳😂';
136135
for (let char of str) {
137-
alert( char ); // 𝒳, and then 😂
136+
alert( char ); // 𝒳, y luego 😂
138137
}
139138
```
140139

141-
## Calling an iterator explicitly
140+
## Llamar a un iterador explícitamente
142141

143-
For deeper understanding let's see how to use an iterator explicitly.
142+
Para una comprensión más profunda, veamos cómo usar un iterador explícitamente.
144143

145-
We'll iterate over a string in exactly the same way as `for..of`, but with direct calls. This code creates a string iterator and gets values from it "manually":
144+
Vamos a iterar sobre una cadena exactamente de la misma manera que `for..of`, pero con llamadas directas. Este código crea un iterador de cadena y obtiene valores de él "manualmente":
146145

146+
 
147147
```js run
148-
let str = "Hello";
148+
let str = "Hola";
149149

150-
// does the same as
150+
// hace lo mismo que
151151
// for (let char of str) alert(char);
152152

153153
*!*
@@ -157,92 +157,93 @@ let iterator = str[Symbol.iterator]();
157157
while (true) {
158158
let result = iterator.next();
159159
if (result.done) break;
160-
alert(result.value); // outputs characters one by one
160+
alert(result.value); // retorna los caracteres uno por uno
161161
}
162162
```
163+
Rara vez se necesita esto, pero nos da más control sobre el proceso que `for..of`. Por ejemplo, podemos dividir el proceso de iteración: iterar un poco, luego parar, hacer otra cosa y luego continuar.
164+
 
165+
## Iterables y array-likes [#array-like]
163166

164-
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.
167+
Hay dos términos oficiales que se parecen, pero son muy diferentes. Asegúrese de comprenderlos bien para evitar confusiones.
168+
 
169+
- *Iterables* son objetos que implementan el método `Symbol.iterator`, como se describió anteriormente.
170+
- *Array-likes* son objetos que tienen índices y `longitud` o *length*, por lo que se ven como matrices.
165171

166-
## Iterables and array-likes [#array-like]
172+
Cuando usamos JavaScript para tareas prácticas en el navegador u otros entornos, podemos encontrar objetos que son iterables o array-like, o ambos.
167173

168-
There are two official terms that look similar, but are very different. Please make sure you understand them well to avoid the confusion.
174+
Por ejemplo, las cadenas son iterables (`for..of` funciona en ellas) y array-like (tienen índices numéricos y `length`).
169175

170-
- *Iterables* are objects that implement the `Symbol.iterator` method, as described above.
171-
- *Array-likes* are objects that have indexes and `length`, so they look like arrays.
176+
Pero un iterable puede no ser array-like. Y viceversa, un array-like puede no ser iterable.
172177

173-
When we use JavaScript for practical tasks in browser or other environments, we may meet objects that are iterables or array-likes, or both.
174178

175-
For instance, strings are both iterable (`for..of` works on them) and array-like (they have numeric indexes and `length`).
179+
Por ejemplo, `range` en el ejemplo anterior es iterable, pero no array-like, porque no tiene propiedades indexadas ni `longitud` o *length*.
176180

177-
But an iterable may be not array-like. And vice versa an array-like may be not iterable.
178181

179-
For example, the `range` in the example above is iterable, but not array-like, because it does not have indexed properties and `length`.
180-
181-
And here's the object that is array-like, but not iterable:
182+
Y aquí está el objeto que tiene forma de matriz, pero no es iterable:
182183

183184
```js run
184-
let arrayLike = { // has indexes and length => array-like
185-
0: "Hello",
186-
1: "World",
185+
let arrayLike = { // tiene índices y longitud => array-like
186+
0: "Hola",
187+
1: "Mundo",
187188
length: 2
188189
};
189190

190191
*!*
191-
// Error (no Symbol.iterator)
192+
// Error (sin Symbol.iterator)
192193
for (let item of arrayLike) {}
193194
*/!*
194195
```
195196

196-
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. E.g. we would like to work with `range` using array methods. How to achieve that?
197+
Tanto los iterables como los array-like generalmente no son *matrices*, no tienen "push", "pop", etc. Eso es bastante inconveniente si tenemos un objeto de este tipo y queremos trabajar con él como con una matriz. P.ej. nos gustaría trabajar con `range` utilizando métodos de matriz. ¿Cómo lograr eso?
197198

198199
## Array.from
199200

200-
There's a universal method [Array.from](mdn:js/Array/from) that takes an iterable or array-like value and makes a "real" `Array` from it. Then we can call array methods on it.
201+
Existe un método universal [Array.from](https://developer.mozilla.org/es/docs/Web/JavaScript/Referencia/Objetos_globales/Array/from) que toma un valor iterable o similar a una matriz y crea un `Array` ¨real¨ a partir de él. De esta manera podemos llamar y usar métodos que pertenecen a una matriz.
201202

202-
For instance:
203+
Por ejemplo:
203204

204205
```js run
205206
let arrayLike = {
206-
0: "Hello",
207-
1: "World",
207+
0: "Hola",
208+
1: "Mundo",
208209
length: 2
209210
};
210211

211212
*!*
212213
let arr = Array.from(arrayLike); // (*)
213214
*/!*
214-
alert(arr.pop()); // World (method works)
215+
alert(arr.pop()); // Mundo (el método pop funciona)
215216
```
216217

217-
`Array.from` at the line `(*)` takes the object, examines it for being an iterable or array-like, then makes a new array and copies all items to it.
218+
`Array.from` en la línea `(*)` toma el objeto, lo examina por ser iterable o similar a una matriz, luego crea una nueva matriz y copia allí todos los elementos.
218219

219-
The same happens for an iterable:
220+
Lo mismo sucede para un iterable:
220221

221222
```js
222-
// assuming that range is taken from the example above
223+
// suponiendo que range se toma del ejemplo anterior
223224
let arr = Array.from(range);
224-
alert(arr); // 1,2,3,4,5 (array toString conversion works)
225+
alert(arr); // 1,2,3,4,5 (la conversión de matriz a cadena funciona)
225226
```
226227

227-
The full syntax for `Array.from` also allows us to provide an optional "mapping" function:
228+
La sintaxis completa para `Array.from` también nos permite proporcionar una función opcional de "mapeo":
228229
```js
229230
Array.from(obj[, mapFn, thisArg])
230231
```
231232

232-
The optional second argument `mapFn` can be a function that will be applied to each element before adding it to the array, and `thisArg` allows us to set `this` for it.
233+
El segundo argumento opcional `mapFn` puede ser una función que se aplicará a cada elemento antes de agregarlo a la matriz, y `thisArg` permite establecer el `this` para ello.
233234

234-
For instance:
235+
Por ejemplo:
235236

236237
```js
237-
// assuming that range is taken from the example above
238+
// suponiendo que range se toma del ejemplo anterior
238239

239-
// square each number
240+
// el cuadrado de cada número
240241
let arr = Array.from(range, num => num * num);
241242

242243
alert(arr); // 1,4,9,16,25
243244
```
244245

245-
Here we use `Array.from` to turn a string into an array of characters:
246+
Aquí usamos `Array.from` para convertir una cadena en una matriz de caracteres:
246247

247248
```js run
248249
let str = '𝒳😂';
@@ -255,24 +256,25 @@ alert(chars[1]); // 😂
255256
alert(chars.length); // 2
256257
```
257258

258-
Unlike `str.split`, it relies on the iterable nature of the string and so, just like `for..of`, correctly works with surrogate pairs.
259-
260-
Technically here it does the same as:
259+
A diferencia de `str.split`, `Array.from` se basa en la naturaleza iterable de la cadena y, por lo tanto, al igual que `for..of`, funciona correctamente con pares sustitutos.
261260

261+
Técnicamente aquí hace lo mismo que:
262+
 
262263
```js run
263264
let str = '𝒳😂';
264265

265-
let chars = []; // Array.from internally does the same loop
266+
let chars = []; // Array.from internamente hace el mismo bucle
267+
266268
for (let char of str) {
267269
chars.push(char);
268270
}
269271

270272
alert(chars);
271273
```
272274

273-
...But it is shorter.
275+
... Pero es más corto.
274276

275-
We can even build surrogate-aware `slice` on it:
277+
Incluso podemos construir un `segmento` o `slice` compatible con sustitutos en él:
276278

277279
```js run
278280
function slice(str, start, end) {
@@ -283,25 +285,26 @@ let str = '𝒳😂𩷶';
283285

284286
alert( slice(str, 1, 3) ); // 😂𩷶
285287

286-
// the native method does not support surrogate pairs
287-
alert( str.slice(1, 3) ); // garbage (two pieces from different surrogate pairs)
288+
// el método nativo no admite pares sustitutos
289+
alert( str.slice(1, 3) ); // garbage (dos piezas de diferentes pares sustitutos)
288290
```
289291

290292

291-
## Summary
292-
293-
Objects that can be used in `for..of` are called *iterable*.
293+
## Resumen
294294

295-
- Technically, iterables must implement the method named `Symbol.iterator`.
296-
- The result of `obj[Symbol.iterator]` is called an *iterator*. It handles the further iteration process.
297-
- An iterator must have the method named `next()` that returns an object `{done: Boolean, value: any}`, here `done:true` denotes the end of the iteration process, otherwise the `value` is the next value.
298-
- The `Symbol.iterator` method is called automatically by `for..of`, but we also can do it directly.
299-
- Built-in iterables like strings or arrays, also implement `Symbol.iterator`.
300-
- String iterator knows about surrogate pairs.
295+
Los objetos que se pueden usar en `for..of` se denominan *iterables*.
301296

297+
- Técnicamente, los iterables deben implementar el método llamado `Symbol.iterator`.
298+
- El resultado de `obj[Symbol.iterator]` se llama *iterador*. Maneja el proceso de iteración adicional.
299+
- Un iterador debe tener el método llamado `next()` que devuelve un objeto `{done: Boolean, value: any}`, donde `done: true` denota el final de la iteración, de lo contrario, `value` es el siguiente valor.
300+
- El método `Symbol.iterator` se llama automáticamente por `for..of`, pero también podemos hacerlo directamente.
301+
- Los iterables integrados, como cadenas o matrices, también implementan `Symbol.iterator`.
302+
- El iterador de cadena funciona con pares sustitutos.
303+
 
302304

303-
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.
305+
Los objetos que tienen propiedades indexadas y `longitud` o *length* se llaman *array-like*. Dichos objetos también pueden tener otras propiedades y métodos, pero carecen de los métodos integrados de las matrices.
304306

305-
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.
307+
Si miramos dentro de la especificación, veremos que la mayoría de los métodos incorporados suponen que funcionan con iterables o array-likes en lugar de matrices "reales", porque eso es más abstracto.
306308

307-
`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.
309+
`Array.from (obj[, mapFn, thisArg])` crea un verdadero `Array` de un `obj` iterable o array-like, y luego podemos usar métodos de matriz en él. Los argumentos opcionales `mapFn` y `thisArg` nos permiten aplicar una función a cada elemento.
310+
 

0 commit comments

Comments
 (0)