cambiar valores en la matriz al hacer foreach

Resuelto rsk82 asked hace 12 años • 11 respuestas

ejemplo:

var arr = ["one","two","three"];

arr.forEach(function(part){
  part = "four";
  return "four";
})

alert(arr);

La matriz todavía tiene sus valores originales, ¿hay alguna forma de tener acceso de escritura a los elementos de la matriz desde la función de iteración?

rsk82 avatar Sep 19 '12 01:09 rsk82
Aceptado

A la devolución de llamada se le pasa el elemento, el índice y la matriz misma.

arr.forEach(function(part, index, theArray) {
  theArray[index] = "hello world";
});

editar : como se indica en un comentario, la .forEach()función puede tomar un segundo argumento, que se usará como valor de thisen cada llamada a la devolución de llamada:

arr.forEach(function(part, index) {
  this[index] = "hello world";
}, arr); // use arr as this

Ese segundo ejemplo arrse muestra configurado como thisen la devolución de llamada. Uno podría pensar que la matriz involucrada en la .forEach()llamada podría ser el valor predeterminado de this, pero por alguna razón no lo es; thislo será undefinedsi no se aporta ese segundo argumento.

(Nota: lo anterior thisno se aplica si la devolución de llamada es una =>función, porque thisnunca está vinculada a nada cuando se invocan dichas funciones).

También es importante recordar que existe toda una familia de utilidades similares proporcionadas en el prototipo de Array, y surgen muchas preguntas en Stackoverflow sobre una función u otra, de modo que la mejor solución es simplemente elegir una herramienta diferente. Tienes:

  • forEachpara hacer algo con o para cada entrada de una matriz;
  • filterpara producir una nueva matriz que contenga sólo entradas calificadas;
  • mappara crear una nueva matriz uno a uno transformando una matriz existente;
  • somecomprobar si al menos un elemento de una matriz se ajusta a alguna descripción;
  • everycomprobar si todas las entradas de una matriz coinciden con una descripción;
  • findbuscar un valor en una matriz

etcétera. enlace MDN

Pointy avatar Sep 18 '2012 18:09 Pointy

Intentemos mantenerlo simple y discutir cómo funciona realmente. Tiene que ver con tipos de variables y parámetros de funciones.

Aquí está el código del que estamos hablando:

var arr = ["one","two","three"];

arr.forEach(function(part) {
  part = "four";
  return "four";
})

alert(arr);

En primer lugar, aquí es donde deberías leer sobre Array.prototype.forEach():

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach

En segundo lugar, hablemos brevemente sobre los tipos de valores en JavaScript.

Las primitivas (indefinida, nula, cadena, booleana, número) almacenan un valor real.

ex:var x = 5;

Los tipos de referencia (objetos personalizados) almacenan la ubicación de memoria del objeto.

ex:var xObj = { x : 5 };

Y tercero, cómo funcionan los parámetros de función.

En las funciones, los parámetros siempre se pasan por valor.

Como arres una matriz de cadenas, es una matriz de objetos primitivos , lo que significa que se almacenan por valor.

Entonces, para el código anterior, esto significa que cada vez que se itera forEach(), partes igual al mismo valor que arr[index], pero no al mismo objeto .

part = "four";Cambiará la partvariable, pero la dejará arrsola.

El siguiente código cambiará los valores que desee:

var arr = ["one","two","three"];

arr.forEach(function(part, index) {
  arr[index] = "four";
});

alert(arr);

Ahora bien, si la matriz arrfuera una matriz de tipos de referencia , el siguiente código funcionará porque los tipos de referencia almacenan una ubicación de memoria de un objeto en lugar del objeto real.

var arr = [{ num : "one" }, { num : "two"}, { num : "three"}];

arr.forEach(function(part, index) {
  // part and arr[index] point to the same object
  // so changing the object that part points to changes the object that arr[index] points to

  part.num = "four";
});

alert(arr[0].num);
alert(arr[1].num);
alert(arr[2].num);

A continuación se ilustra que puede cambiar partpara que apunte a un nuevo objeto mientras deja los objetos almacenados arrsolos:

var arr = [{ num : "one" }, { num : "two"}, { num : "three"}];

arr.forEach(function(part, index) {
  // the following will not change the object that arr[index] points to because part now points at a new object
  part = 5;
});

alert(arr[0].num);
alert(arr[1].num);
alert(arr[2].num);
Dave avatar Jul 08 '2015 16:07 Dave

Matriz: [1, 2, 3, 4]
Resultado:["foo1", "foo2", "foo3", "foo4"]

Array.prototype.map()Mantener la matriz original

const originalArr = ["Iron", "Super", "Ant", "Aqua"];
const modifiedArr = originalArr.map(name => `${name}man`);

console.log( "Original: %s", originalArr );
console.log( "Modified: %s", modifiedArr );
Expandir fragmento

Array.prototype.map()Anular la matriz original

let originalArr = ["Iron", "Super", "Ant", "Aqua"];
originalArr = originalArr.map(name => `${name}man`);

console.log( "Original: %s", originalArr );
Expandir fragmento

Array.prototype.forEach()Anular la matriz original

const originalArr = ["Iron", "Super", "Ant", "Aqua"];
originalArr.forEach((name, index) => originalArr[index] = `${name}man`);

console.log( "Overridden: %s", originalArr );
Expandir fragmento

Roko C. Buljan avatar Jul 08 '2016 12:07 Roko C. Buljan

Javascript se pasa por valor, y lo que esencialmente significa partes una copia del valor en la matriz.

Para cambiar el valor, acceda a la matriz en su bucle.

arr[index] = 'new value';

hvgotcodes avatar Sep 18 '2012 18:09 hvgotcodes