aboutsummaryrefslogtreecommitdiff
path: root/files/es/web/javascript/guide/colecciones_indexadas/index.html
blob: baf55a84d5fc259a6c96815da5d72864a3beb06a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
---
title: Colecciones indexadas
slug: Web/JavaScript/Guide/colecciones_indexadas
tags:
  - Array
  - Arreglo
  - Guía
  - JavaScript
  - 'l10n:priority'
translation_of: Web/JavaScript/Guide/Indexed_collections
---
<div>{{jsSidebar("JavaScript Guide")}} {{PreviousNext("Web/JavaScript/Guide/Regular_Expressions", "Web/JavaScript/Guide/Keyed_Collections")}}</div>

<p class="summary">Este capítulo presenta colecciones de datos ordenados por un valor de índice. Esto incluye arreglos y construcciones similares a arreglos tal como objetos {{jsxref("Array")}} y objetos {{jsxref("TypedArray")}}.</p>

<h2 id="El_objeto_Array">El objeto <code>Array</code></h2>

<p>Un <em><dfn>array</dfn></em> es una lista ordenada de valores a los que te refieres con un nombre y un índice.</p>

<p>Por ejemplo, considera un arreglo llamado <code>emp</code>, que contiene los nombres de los empleados indexados por su id de empleado numérico. De tal modo que <code>emp[0]</code> sería el empleado número cero, <code>emp[1]</code> el empleado número uno, y así sucesivamente.</p>

<p>JavaScript no tiene un tipo de dato <code>array</code> explícito. Sin embargo, puedes utilizar el objeto <code>Array</code> predefinido y sus métodos para trabajar con arreglos en tus aplicaciones. El objeto <code>Array</code> tiene métodos para manipular arreglos de varias formas, tal como unirlos, invertirlos y ordenarlos. Tiene una propiedad para determinar la longitud del arreglo y otras propiedades para usar con expresiones regulares.</p>

<h3 id="Crear_un_arreglo">Crear un arreglo</h3>

<p>Las siguientes declaraciones crean arreglos equivalentes:</p>

<pre class="brush: js notranslate">let arr = new Array(<var>element0</var>, <var>element1</var>, ..., <var>elementN</var>)
let arr = Array(<var>element0</var>, <var>element1</var>, ..., <var>elementN</var>)
let arr = [<var>element0</var>, <var>element1</var>, ..., <var>elementN</var>]
</pre>

<p><code><var>element0</var>, <var>element1</var>, ..., <var>elementN</var></code> es una lista de valores para los elementos del arreglo. Cuando se especifican estos valores, el arreglo se inicia con ellos como elementos del arreglo. La propiedad <code>length</code> del arreglo se establece en el número de argumentos.</p>

<p>La sintaxis de corchetes se denomina "arreglo literal" o "iniciador de arreglo". Es más corto que otras formas de creación de arreglos, por lo que generalmente se prefiere. Consulta <a href="/es/docs/Web/JavaScript/Guide/Grammar_and_types#Arreglos_literales">Arreglos literales</a> para obtener más detalles.</p>

<p>Para crear un arreglo con una longitud distinta de cero, pero sin ningún elemento, se puede utilizar cualquiera de las siguientes:</p>

<pre class="brush: js notranslate">// Esta...
let arr = new Array(<var>arrayLength</var>)

// ...da como resultado el mismo arreglo que este
let arr = Array(<var>arrayLength</var>)


// Esto tiene exactamente el mismo efecto
let arr = []
arr.length = <var>arrayLength</var>
</pre>

<div class="note">
<p><strong>Nota</strong>: En el código anterior, <code><var>arrayLength</var></code> debe ser un <code>Número</code>. De lo contrario, se creará un arreglo con un solo elemento (el valor proporcionado). Llamar a <code>arr.length</code> devolverá <code><var>arrayLength</var></code>, pero el arreglo no contiene ningún elemento. Un bucle {{jsxref("Statements/for...in", "for...in")}} no encontrarás ninguna propiedad en el arreglo.</p>
</div>

<p>Además de una variable recién definida como se muestra arriba, los arreglos también se pueden asignar como una propiedad a un objeto nuevo o existente:</p>

<pre class="brush: js notranslate">let obj = {}
// ...
obj.prop = [element0, element1, ..., elementN]

// O
let obj = {prop: [element0, element1, ...., elementN]}
</pre>

<p>Si deseas iniciar un arreglo con un solo elemento, y el elemento resulta ser un <code>Número</code>, debes usar la sintaxis de corchetes. Cuando se pasa un solo valor <code>Number</code> al constructor o función <code>Array()</code>, se interpreta como un <code>arrayLength</code>, no como un solo elemento.</p>

<pre class="brush: js notranslate">let arr = [42]       // Crea un arreglo con un solo elemento:
                     // el número 42.

let arr = Array(42)  // Crea un arreglo sin elementos
                     // y arr.length establecidos en 42.
                     //
                     // Esto es equivalente a:
let arr = []
arr.length = 42
</pre>

<p>Llamar a <code>Array(<var>N</var>)</code> da como resultado un <code>RangeError</code>, si <code><var>N</var></code> no es un número entero cuya porción fraccionaria no es cero. El siguiente ejemplo ilustra este comportamiento.</p>

<pre class="brush: js notranslate">let arr = Array(9.3)   // RangeError: Longitud de arreglo no válida
</pre>

<p>Si tu código necesita crear arreglos con elementos únicos de un tipo de dato arbitrario, es más seguro utilizar arreglos literales. Alternativamente, crea un arreglo vacío primero antes de agregarle el único elemento.</p>

<p>En ES2015, puedes utilizar el método estático {{jsxref("Array.of")}} para crear arreglos con un solo elemento.</p>

<pre class="brush: js notranslate">let wisenArray = Array.of(9.3)   // wisenArray contiene solo un elemento 9.3</pre>

<h3 id="Refiriéndose_a_elementos_del_arreglo">Refiriéndose a elementos del arreglo</h3>

<p>Dado que los elementos también son propiedades, puedes acceder a ellos usando la <a href="/es/docs/Web/JavaScript/Reference/Operators/Property_Accessors">propiedad <code>accessors</code></a>. Supongamos que defines el siguiente arreglo:</p>

<pre class="brush: js notranslate">let myArray = ['Wind', 'Rain', 'Fire']
</pre>

<p>Puedes referirte al primer elemento del arreglo como <code>myArray[0]</code>, al segundo elemento del arreglo como <code>myArray[1]</code>, etc<span class="st"></span> El índice de los elementos comienza en cero.</p>

<div class="note">
<p><strong>Nota</strong>: También puedes utilizar la <a href="/es/docs/Web/JavaScript/Reference/Operators/Property_Accessors">propiedad <code>accessors</code></a> para acceder a otras propiedades del arreglo, como con un objeto.</p>

<pre class="brush: js notranslate">let arr = ['one', 'two', 'three']
arr[2]          // three
arr['length']   // 3
</pre>
</div>

<h3 id="Llenar_un_arreglo">Llenar un arreglo</h3>

<p>Puedes llenar un arreglo asignando valores a sus elementos. Por ejemplo:</p>

<pre class="brush: js notranslate">let emp = []
emp[0] = 'Casey Jones'
emp[1] = 'Phil Lesh'
emp[2] = 'August West'
</pre>

<div class="note">
<p><strong>Nota</strong>: Si proporcionas un valor no entero al operador <code>array</code> en el código anterior, se creará una propiedad en el objeto que representa al arreglo, en lugar de un elemento del arreglo.</p>

<pre class="brush: js notranslate">let arr = []
arr[3.4] = 'Oranges'
console.log(arr.length)                 // 0
console.log(arr.hasOwnProperty(3.4))    // true
</pre>
</div>

<p>También puedes rellenar un arreglo cuando lo creas:</p>

<pre class="brush: js notranslate">let myArray = new Array('Hello', myVar, 3.14159)
// OR
let myArray = ['Mango', 'Apple', 'Orange']
</pre>

<h3 id="Entendiendo_length">Entendiendo <code>length</code></h3>

<p>A nivel de implementación, los arreglos de JavaScript almacenan sus elementos como propiedades de objeto estándar, utilizando el índice del arreglo como nombre de propiedad.</p>

<p>La propiedad <code>length</code> es especial. Siempre devuelve el índice del último elemento más uno. (En el siguiente ejemplo, <code>'Dusty'</code> está indexado en <code>30</code>, por lo que <code>cats.length</code> devuelve <code>30 + 1</code>).</p>

<p>Recuerda, los índices del Array JavaScript están basados en 0: comienzan en <code>0</code>, no en <code>1</code>. Esto significa que la propiedad <code>length</code> será uno más que el índice más alto almacenado en el arreglo:</p>

<pre class="brush: js notranslate">let cats = []
cats[30] = ['Dusty']
console.log(cats.length) // 31
</pre>

<p>También puedes asignar la propiedad <code>length</code>.</p>

<p>Escribir un valor que sea más corto que el número de elementos almacenados trunca el arreglo. Escribir <code>0</code> lo vacía por completo:</p>

<pre class="brush: js notranslate">let cats = ['Dusty', 'Misty', 'Twiggy']
console.log(cats.length)  // 3

cats.length = 2
console.log(cats)  // logs "Dusty, Misty" - Twiggy se ha eliminado

cats.length = 0
console.log(cats)  // logs []; el arreglo cats está vacío

cats.length = 3
console.log(cats)  // logs [ &lt;3 elementos vacíos&gt; ]
</pre>

<h3 id="Iterando_sobre_arreglos">Iterando sobre arreglos</h3>

<p>Una operación común es iterar sobre los valores de un arreglo, procesando cada uno de alguna manera. La forma más sencilla de hacerlo es la siguiente:</p>

<pre class="brush: js notranslate">let colors = ['red', 'green', 'blue']
for (let i = 0; i &lt; colors.length; i++) {
  console.log(colors[i])
}
</pre>

<p>Si sabes que ninguno de los elementos de tu arreglo se evalúa como <code>false</code> en un contexto booleano, si tu arreglo consta solo de nodos <a href="/es/docs/DOM" title="/es/docs/DOM">DOM</a>, por ejemplo, puedes usar un lenguaje eficiente:</p>

<pre class="brush: js notranslate">let divs = document.getElementsByTagName('div')
for (let i = 0, div; div = divs[i]; i++) {
  /* Procesar div de alguna manera */
}
</pre>

<p>Esto evita la sobrecarga de verificar la longitud del arreglo y garantiza que la variable <code><var>div</var></code> se reasigne al elemento actual cada vez que se realiza el bucle para mayor comodidad.</p>

<p>El método {{jsxref("Array.forEach", "forEach()")}} proporciona otra forma de iterar sobre un arreglo:</p>

<pre class="brush: js notranslate">let colors = ['red', 'green', 'blue']
colors.forEach(function(color) {
  console.log(color)
})
// red
// green
// blue
</pre>

<p>Alternativamente, puedes acortar el código para el parámetro <code>forEach</code> con las funciones de flecha ES2015:</p>

<pre class="brush: js notranslate">let colors = ['red', 'green', 'blue']
colors.forEach(color =&gt; console.log(color))
// red
// green
// blue
</pre>

<p>La función pasada a <code>forEach</code> se ejecuta una vez por cada elemento del arreglo, con el elemento de arreglo pasado como argumento de la función. Los valores no asignados no se iteran en un bucle <code>forEach</code>.</p>

<p>Ten en cuenta que los elementos de un arreglo que se omiten cuando se define el arreglo no se enumeran cuando lo itera <code>forEach</code>, pero <em>se enumeran</em> cuando <code>undefined</code> se ha asignado manualmente al elemento:</p>

<pre class="brush: js notranslate">let array = ['first', 'second', , 'fourth']

array.forEach(function(element) {
  console.log(element)
})
// first
// second
// fourth

if (array[2] === undefined) {
  console.log('array[2] is undefined')  // true
}

array = ['first', 'second', undefined, 'fourth']

array.forEach(function(element) {
  console.log(element)
})
// first
// second
// undefined
// fourth
</pre>

<p>Dado que los elementos de JavaScript se guardan como propiedades de objeto estándar, no es recomendable iterar a través de arreglos de JavaScript usando bucles {{jsxref("Statements/for...in", "for...in")}}, porque se enumerarán los elementos normales y todas las propiedades enumerables.</p>

<h3 id="Métodos_de_array">Métodos de array</h3>

<p>El objeto {{jsxref("Array")}} tiene los siguientes métodos:</p>

<p>{{jsxref("Array.concat", "concat()")}} une dos o más arreglos y devuelve un nuevo arreglo.</p>

<pre class="brush: js notranslate">let myArray = new Array('1', '2', '3')
myArray = myArray.concat('a', 'b', 'c')
// myArray is now ["1", "2", "3", "a", "b", "c"]
</pre>

<p>{{jsxref("Array.join", "join(delimiter = ',')")}} une todos los elementos de un arreglo en una cadena.</p>

<pre class="brush: js notranslate">let myArray = new Array('Viento', 'Lluvia', 'Fuego')
let list = myArray.join('-')   // la lista es "Viento - Lluvia - Fuego"
</pre>

<p>{{jsxref("Array.push", "push()")}} agrega uno o más elementos al final de un arreglo y devuelve la <code>longitud</code> resultante del arreglo.</p>

<pre class="brush: js notranslate">let myArray = new Array('1', '2')
myArray.push('3') // myArray ahora es ["1", "2", "3"]
</pre>

<p>{{jsxref("Array.pop", "pop()")}} elimina el último elemento de un arreglo y devuelve ese elemento.</p>

<pre class="brush: js notranslate">let myArray = new Array ('1', '2', '3')
let last = myArray.pop()
// myArray ahora es ["1", "2"], last = "3"
</pre>

<p>{{jsxref("Array.shift", "shift()")}} elimina el primer elemento de un arreglo y devuelve ese elemento.</p>

<pre class="brush: js notranslate">let myArray = new Array ('1', '2', '3')
let first = myArray.shift()
// myArray ahora es ["2", "3"], first es "1"
</pre>

<p>{{jsxref("Array.unshift", "unshift()")}} agrega uno o más elementos al frente de un arreglo y devuelve la nueva longitud del arreglo.</p>

<pre class="brush: js notranslate">let myArray = new Array('1', '2', '3')
myArray.unshift('4', '5')
// myArray se convierte en ["4", "5", "1", "2", "3"]
</pre>

<p>{{jsxref("Array.slice", "slice(start_index, upto_index)")}} extrae una sección de un arreglo y devuelve un nuevo arreglo.</p>

<pre class="brush: js notranslate">let myArray = new Array('a', 'b', 'c', 'd', 'e')
myArray = myArray.slice(1, 4) // comienza en el índice 1 y extrae todos los elementos
                               // hasta el índice 3, devuelve ["b", "c", "d"]
</pre>

<p>{{jsxref("Array.splice", "splice(index, count_to_remove, addElement1, addElement2, ...)")}} elimina elementos de un arreglo y (opcionalmente) los reemplaza. Devuelve los elementos que se eliminaron del arreglo.</p>

<pre class="brush: js notranslate">let myArray = new Array('1', '2', '3', '4', '5')
myArray.splice(1, 3, 'a', 'b', 'c', 'd')
// myArray ahora es ["1", "a", "b", "c", "d", "5"]
// Este código comenzó en el índice uno (o donde estaba el "2"),
// eliminó 3 elementos allí, y luego insertó todos los consecutivos
// elementos en su lugar.
</pre>

<p>{{jsxref("Array.reverse", "reverse()")}} transpone los elementos de un arreglo, en su lugar: el primer elemento del arreglo se convierte en el último y el último en el primero. Devuelve una referencia al arreglo.</p>

<pre class="brush: js notranslate">let myArray = new Array ('1', '2', '3')
myArray.reverse()
// transpone el arreglo para que myArray = ["3", "2", "1"]
</pre>

<p>{{jsxref("Array.sort", "sort()")}} ordena los elementos de un arreglo en su lugar y devuelve una referencia al arreglo.</p>

<pre class="brush: js notranslate">let myArray = new Array('Viento', 'Lluvia', 'Fuego')
myArray.sort()
// ordena el arreglo para que myArray = ["Fuego", "Lluvia", "Viento"]
</pre>

<p><code>sort()</code> también puede tomar una función retrollamada para determinar cómo se comparan los elementos del arreglo.</p>

<p>El método <code>sort</code> (y otros a continuación) que reciben una retrollamada se conocen como <em>métodos iterativos</em>, porque iteran sobre todo el arreglo de alguna manera. Cada uno toma un segundo argumento opcional llamado <code><var>thisObject</var></code>. Si se proporciona, <code><var>thisObject</var></code> se convierte en el valor de la palabra clave <code>this</code> dentro del cuerpo de la función retrollamada. Si no se proporciona, como en otros casos en los que se invoca una función fuera de un contexto de objeto explícito, <code>this</code> se referirá al objeto global (<a href="/es/docs/Web/API/Window" title="La interfaz &lt;code>Window&lt;/code> representa una ventana que contiene un documento DOM; la propiedad &lt;code>document&lt;/code> apunta al documento DOM cargado en esa ventana."><code>window</code></a>) cuando se usa la función de flecha como retrollamada, o <code>undefined</code> cuando se usa una función normal como retrollamada.</p>

<p>La función retrollamada se invoca con dos argumentos, que son elementos del arreglo.</p>

<p>La siguiente función compara dos valores y devuelve uno de tres valores:</p>

<p>Por ejemplo, lo siguiente se ordenará por la última letra de una cadena:</p>

<pre class="brush: js notranslate">let sortFn = function(a, b) {
  if (a[a.length - 1] &lt; b[b.length - 1]) return -1;
  if (a[a.length - 1] &gt; b[b.length - 1]) return 1;
  if (a[a.length - 1] == b[b.length - 1]) return 0;
}
myArray.sort(sortFn)
// ordena el arreglo para que myArray = ["Viento", "Fuego", "Lluvia"]</pre>

<ul>
 <li>si <code><var>a</var></code> es menor que <code><var>b</var></code> por el sistema de clasificación, devuelve <code>-1</code> ( o cualquier número negativo)</li>
 <li>si <code><var>a</var></code> es mayor que <code><var>b</var></code> por el sistema de clasificación, devuelve <code>1</code> (o cualquier número positivo)</li>
 <li>si <code><var>a</var></code> y <code><var>b</var></code> se consideran equivalentes, devuelve <code>0</code>.</li>
</ul>

<p>{{jsxref("Array.indexOf", "indexOf (searchElement[, fromIndex])")}} busca en el arreglo <code><var>searchElement</var></code> y devuelve el índice de la primera coincidencia.</p>

<pre class="brush: js notranslate">let a = ['a', 'b', 'a', 'b', 'a']
console.log(a.indexOf('b')) // registros 1

// Ahora inténtalo de nuevo, comenzando después de la última coincidencia
console.log(a.indexOf('b', 2)) // registra 3
console.log(a.indexOf('z')) // logs -1, porque no se encontró 'z'
</pre>

<p>{{jsxref("Array.lastIndexOf", "lastIndexOf(searchElement [, fromIndex])")}} funciona como <code>indexOf</code>, pero comienza al final y busca hacia atrás.</p>

<pre class="brush: js notranslate">let​a = ['a', 'b', 'c', 'd', 'a', 'b']
console.log(a.lastIndexOf('b')) // registra 5

// Ahora inténtalo de nuevo, comenzando desde antes de la última coincidencia
console.log(a.lastIndexOf('b', 4)) // registra 1
console.log(a.lastIndexOf('z'))    // registra -1
</pre>

<p>{{jsxref("Array.forEach", "forEach(callback[, thisObject])")}} ejecuta <code><var>callback</var></code> en cada elemento del arreglo y devuelve <code>undefined</code>.</p>

<pre class="brush: js notranslate">let​a = ['a', 'b', 'c']
a.forEach(function(elemento) { console.log(elemento) })
// registra cada elemento por turno
</pre>

<p>{{jsxref("Array.map", "map(callback [, thisObject])")}} devuelve un nuevo arreglo del valor de retorno de ejecutar <code><var>callback</var></code> en cada elemento del arreglo.</p>

<pre class="brush: js notranslate">let a1 = ['a', 'b', 'c']
let a2 = a1.map(function(item) { return item.toUpperCase() })
console.log(a2) // registra ['A', 'B', 'C']
</pre>

<p>{{jsxref("Array.filter", "filter(callback [, thisObject])")}} devuelve un nuevo arreglo que contiene los elementos para los cuales <code><var>callback</var></code> devolvió <code>true</code>.</p>

<pre class="brush: js notranslate">let a1 = ['a', 10, 'b', 20, 'c', 30]
let a2 = a1.filter(function(item) { return typeof item === 'number'; })
console.log(a2)  // registra [10, 20, 30]
</pre>

<p>{{jsxref("Array.every", "every(callback [, thisObject])")}} devuelve <code>true</code> si <code><var>callback</var></code> devuelve <code>true</code> para cada elemento del arreglo.</p>

<pre class="brush: js notranslate">function isNumber(value) {
  return typeof value === 'number'
}
let a1 = [1, 2, 3]
console.log(a1.every(isNumber))  // registra true
let a2 = [1, '2', 3]
console.log(a2.every(isNumber))  // registra false
</pre>

<p>{{jsxref("Array.some", "some(callback[, thisObject])")}} devuelve <code>true</code> si <code><var>callback</var></code> devuelve <code>true</code> para al menos un elemento del arreglo.</p>

<pre class="brush: js notranslate">function isNumber(value) {
  return typeof value === 'number'
}
let a1 = [1, 2, 3]
console.log(a1.some(isNumber))  // registra true
let a2 = [1, '2', 3]
console.log(a2.some(isNumber))  // registra true
let a3 = ['1', '2', '3']
console.log(a3.some(isNumber))  // registra false
</pre>

<p>{{jsxref("Array.reduce", "reduce(callback[, initialValue])")}} aplica <code><var>callback</var>(<var>acumulador</var>, <var>currentValue</var>[, <var>currentIndex</var>[,<var>array</var>]])</code> para cada valor en el arreglo con el fin de reducir la lista de elementos a un solo valor. La función <code>reduce</code> devuelve el valor final devuelto por la función <code><var>callback</var></code></p>

<p>Si se especifica <code><var>initialValue</var></code>, entonces <code><var>callback</var></code> se llama con <code><var>initialValue</var></code> como primer valor de parámetro y el valor del primer elemento del arreglo como segundo valor de parámetro. </p>

<p>Si <code><var>initialValue</var></code> <em>no</em> es especificado, entonces <code><var>callback</var></code> los primeros dos valores de parámetro deberán ser el primer y segundo elemento del arreglo. En <em>cada</em> llamada subsiguiente, el valor del primer parámetro será el valor de <code><var>callback</var></code> devuelto en la llamada anterior, y el valor del segundo parámetro será el siguiente valor en el arreglo.</p>

<p>Si <code><var>callback</var></code> necesita acceso al índice del elemento que se está procesando, al acceder al arreglo completo, están disponibles como parámetros opcionales.</p>

<pre class="brush: js notranslate">let​a = [10, 20, 30]
let total = a.reduce(function(accumulator, currentValue) { return accumulator + currentValue }, 0)
console.log(total) // Imprime 60
</pre>

<p>{{jsxref("Array.reduceRight", "reduceRight(callback[, initialValue])")}} funciona como <code>reduce()</code>, pero comienza con el último elemento.</p>

<p><code>reduce</code> y <code>reduceRight</code> son los menos obvios de los métodos de arreglo iterativos. Se deben utilizar para algoritmos que combinan dos valores de forma recursiva para reducir una secuencia a un solo valor.</p>

<h3 id="Arreglos_multidimensionales">Arreglos multidimensionales</h3>

<p>Los arreglos se pueden anidar, lo cual significa que un arreglo puede contener otro arreglo como elemento. Usando esta característica de los arreglos de JavaScript, se pueden crear arreglos multidimensionales.</p>

<p>El siguiente código crea un arreglo bidimensional.</p>

<pre class="brush: js notranslate">let a = new Array(4)
for (let i = 0; i &lt; 4; i++) {
  a[i] = new Array(4)
  for (let j = 0; j &lt; 4; j++) {
    a[i][j] = '[' + i + ', ' + j + ']'
  }
}
</pre>

<p>Este ejemplo crea un arreglo con las siguientes filas:</p>

<pre class="notranslate">Row 0: [0, 0] [0, 1] [0, 2] [0, 3]
Row 1: [1, 0] [1, 1] [1, 2] [1, 3]
Row 2: [2, 0] [2, 1] [2, 2] [2, 3]
Row 3: [3, 0] [3, 1] [3, 2] [3, 3]
</pre>

<h3 id="Usar_arreglos_para_almacenar_otras_propiedades">Usar arreglos para almacenar otras propiedades</h3>

<p>Los arreglos también se pueden utilizar como objetos para almacenar información relacionada.</p>

<pre class="brush: js notranslate"><code>const arr = [1, 2, 3];
arr.property = "value";
console.log(arr.property);  // Registra "value"</code>
</pre>

<h3 id="Arreglos_y_expresiones_regulares">Arreglos y expresiones regulares</h3>

<p>Cuando un arreglo es el resultado de una coincidencia entre una expresión regular y una cadena, el arreglo devuelve propiedades y elementos que proporcionan información sobre la coincidencia. Un arreglo es el valor de retorno de {{jsxref("Global_Objects/RegExp/exec", "RegExp.exec()")}}, {{jsxref("Global_Objects/String/match", "String.match()")}} y {{jsxref("Global_Objects/String/split", "String.split()")}}. Para obtener información sobre el uso de arreglos con expresiones regulares, consulta <a href="/es/docs/Web/JavaScript/Guide/Regular_Expressions">Expresiones regulares</a>.</p>

<h3 id="Trabajar_con_objetos_tipo_array">Trabajar con objetos tipo array</h3>

<p>Algunos objetos JavaScript, como <a href="/es/docs/Web/API/NodeList" title="Los objetos &lt;code>NodeList&lt;/code> son colecciones de nodos, generalmente devueltos por propiedades como ↑Node.childNodes↓ y métodos como ↑document.querySelectorAll()↓."><code>NodeList</code></a> devueltos por <a href="/es/docs/Web/API/Document/getElementsByTagName" title="devuelve una &lt;code>HTMLCollection&lt;/code> de elementos con el nombre de etiqueta dado."><code>document.getElementsByTagName()</code></a> o un objeto {{jsxref("Functions/arguments", "arguments")}} disponible dentro del cuerpo de una función, se ven y se comportan como arreglos en la superficie pero no comparten todos sus métodos. El objeto <code>arguments</code> proporciona un atributo {{jsxref("Global_Objects/Function/length", "length")}} pero no implementa el método {{jsxref("Array.forEach", "forEach()")}}, por ejemplo.</p>

<p>Los métodos de arreglo no se pueden llamar directamente en objetos similares a un arreglo.</p>

<pre class="brush: js example-bad notranslate"><code>function printArguments() {
  arguments.forEach(function(item) {// <span class="message-body-wrapper"><span class="message-flex-body"><span class="devtools-monospace message-body"><span class="objectBox-stackTrace reps-custom-format">TypeError: <span class="objectBox objectBox-string">arguments.forEach no es una función</span></span></span></span></span>
    console.log(item);
  });
}</code>
</pre>

<p>Pero puedes llamarlos indirectamente usando {{jsxref("Global_Objects/Function/call", "Function.prototype.call()")}}.</p>

<pre class="brush: js example-good notranslate"><code>function printArguments() {
  Array.prototype.forEach.call(arguments, function(item) {
    console.log(item);
  });
}</code>
</pre>

<p>Los métodos de prototipos de arreglos también se pueden utilizar en cadenas, ya que proporcionan acceso secuencial a sus caracteres de forma similar a los arreglos:</p>

<pre class="brush: js notranslate">Array.prototype.forEach.call('a string', function(chr) {
  console.log(chr)
})
</pre>

<h2 id="Arrays_tipados">Arrays tipados</h2>

<p><a href="/es/docs/Web/JavaScript/Typed_arrays">Los arreglos tipados en JavaScript</a> son objetos similares a arreglos y proporcionan un mecanismo para acceder a datos binarios sin procesar. Como ya sabes, los objetos {{jsxref("Array")}} crecen y se encogen dinámicamente y pueden tener cualquier valor de JavaScript. Los motores de JavaScript realizan optimizaciones para que estos arreglos sean rápidos. Sin embargo, a medida que las aplicaciones web se vuelven cada vez más poderosas, agregando características como manipulación de audio y video, acceso a datos sin procesar usando <a href="/es/docs/WebSockets">WebSockets</a>, y así sucesivamente, ha quedado claro que hay momentos en los que sería útil para que el código JavaScript pueda manipular rápida y fácilmente datos binarios sin procesar en arreglos tipados.</p>

<h3 id="Búferes_y_vistas_arquitectura_de_los_arreglos_con_tipo">Búferes y vistas: arquitectura de los arreglos con tipo</h3>

<p>Para lograr la máxima flexibilidad y eficiencia, los arreglos de JavaScript dividen la implementación en <strong>búferes</strong> y <strong>vistas</strong>. Un búfer (implementado por el objeto {{jsxref("ArrayBuffer")}} es un objeto que representa una porción de datos; no tiene un formato del que hablar y no ofrece ningún mecanismo para acceder a su contenido. Para acceder a la memoria contenida en un búfer, necesitas usar una vista. Una vista proporciona un <strong>contexto </strong>, es decir, un tipo de datos, un desplazamiento inicial y un número de elementos, que convierte los datos en un arreglo con tipo real.</p>

<p><img alt="Arreglos tipados en un &lt;code>ArrayBuffer&lt;/code>" src="https://mdn.mozillademos.org/files/8629/typed_arrays.png" style="height: 278px; width: 666px;"></p>

<h3 id="ArrayBuffer"><code>ArrayBuffer</code></h3>

<p>{{jsxref("ArrayBuffer")}} es un tipo de dato que se utiliza para representar un búfer de datos binarios genérico de longitud fija. No puedes manipular directamente el contenido de un <code>ArrayBuffer</code>; en su lugar, creas una vista de arreglo con tipo o un {{jsxref("DataView")}} que representa el búfer en un formato específico, y lo usa para leer y escribir el contenido del búfer.</p>

<h3 id="Vistas_de_arreglos_tipados">Vistas de arreglos tipados</h3>

<p>Las vistas de arreglos tipados tienen nombres autodescriptivos y proporcionan vistas para todos los tipos numéricos habituales como <code>Int8</code>, <code>Uint32</code>, <code>Float64</code> y así sucesivamente. Hay una vista de arreglo con tipo especial, {jsxref("Uint8ClampedArray")}}, que fija los valores entre <code>0</code> y <code>255</code>. Esto es útil para <a href="/es/docs/Web/API/ImageData">procesamiento de datos de Canvas</a>, por ejemplo.</p>

<table class="standard-table">
 <thead>
  <tr>
   <th class="header" scope="col">Tipo</th>
   <th class="header" scope="col">Rango de valores</th>
   <th class="header" scope="col">Tamaño en bytes</th>
   <th class="header" scope="col">Descripción</th>
   <th class="header" scope="col">Tipo de IDL web</th>
   <th class="header" scope="col">Tipo C equivalente</th>
  </tr>
 </thead>
 <tbody>
  <tr>
   <td>{{jsxref("Int8Array")}}</td>
   <td><code>-128</code> a <code>127</code></td>
   <td>1</td>
   <td>Dos enteros complementarios de 8 bits con signo</td>
   <td><code>byte</code></td>
   <td><code>int8_t</code></td>
  </tr>
  <tr>
   <td>{{jsxref("Uint8Array")}}</td>
   <td><code>0</code> a <code>255</code></td>
   <td>1</td>
   <td>Entero de 8-bit sin signo</td>
   <td><code>octeto</code></td>
   <td><code>uint8_t</code></td>
  </tr>
  <tr>
   <td>{{jsxref("Uint8ClampedArray")}}</td>
   <td><code>0</code> a <code>255</code></td>
   <td>1</td>
   <td>Entero de 8 bits sin signo (sujeto)</td>
   <td><code>octeto</code></td>
   <td><code>uint8_t</code></td>
  </tr>
  <tr>
   <td>{{jsxref("Int16Array")}}</td>
   <td><code>-32768</code> a <code>32767</code></td>
   <td>2</td>
   <td>Dos enteros complementarios de 16 bits con signo</td>
   <td><code>short</code></td>
   <td><code>int16_t</code></td>
  </tr>
  <tr>
   <td>{{jsxref("Uint16Array")}}</td>
   <td><code>0</code> a <code>65535</code></td>
   <td>2</td>
   <td>Entero de 16 bits sin signo</td>
   <td><code>short sin signo</code></td>
   <td><code>uint16_t</code></td>
  </tr>
  <tr>
   <td>{{jsxref("Int32Array")}}</td>
   <td><code>-2147483648</code> a <code>2147483647</code></td>
   <td>4</td>
   <td>dos enteros complementarios de 32 bits con signo</td>
   <td><code>long</code></td>
   <td><code>int32_t</code></td>
  </tr>
  <tr>
   <td>{{jsxref("Uint32Array")}}</td>
   <td><code>0</code> a <code>4294967295</code></td>
   <td>4</td>
   <td>Enteros de 32 bits sin signo</td>
   <td><code>long sin signo</code></td>
   <td><code>uint32_t</code></td>
  </tr>
  <tr>
   <td>{{jsxref("Float32Array")}}</td>
   <td><code>1.2</code><span>×</span><code>10<sup>-38</sup></code> a <code>3.4</code><span>×</span><code>10<sup>38</sup></code></td>
   <td>4</td>
   <td>Número de coma flotante IEEE de 32 bits (7 dígitos significativos, p. ej., <code>1.1234567</code>)</td>
   <td><code>float sin restricciones</code></td>
   <td><code>float</code></td>
  </tr>
  <tr>
   <td>{{jsxref("Float64Array")}}</td>
   <td><code>5.0</code><span>×</span><code>10<sup>-324</sup></code> a <code>1.8</code><span>×</span><code>10<sup>308</sup></code></td>
   <td>8</td>
   <td>Número de coma flotante IEEE de 64 bits (16 dígitos significativos, por ejemplo,<code>1.123 ... 15</code>)</td>
   <td><code>double sin restricciones</code></td>
   <td><code>double</code></td>
  </tr>
  <tr>
   <td>{{jsxref("BigInt64Array")}}</td>
   <td><code>-2<sup>63</sup></code> a <code>2<sup>63</sup>-1</code></td>
   <td>8</td>
   <td>Dos enteros complementarios de 64 bits con signo</td>
   <td><code>bigint</code></td>
   <td><code>int64_t (long long con signo)</code></td>
  </tr>
  <tr>
   <td>{{jsxref("BigUint64Array")}}</td>
   <td><code>0</code> a <code>2<sup>64</sup>-1</code></td>
   <td>8</td>
   <td>Entero de 64 bits sin signo</td>
   <td><code>bigint</code></td>
   <td><code>uint64_t (long long sin signo)</code></td>
  </tr>
 </tbody>
</table>

<p>Para obtener más información, consulta <a href="/es/docs/Web/JavaScript/Typed_arrays">Arreglos tipados en JavaScript</a> y la documentación de referencia para los diferentes objetos {{jsxref("TypedArray")}}.</p>

<p>{{PreviousNext("Web/JavaScript/Guide/Regular_Expressions", "Web/JavaScript/Guide/Keyed_Collections")}}</p>