Quería agregar los elementos de una matriz a otra, así que intenté esto:
[1,2] + [3,4]
Respondió con:
"1,23,4"
Que esta pasando?
[5,6,7][1,2]
es 7
porque usa el último elemento de la segunda matriz. Oo
Quería agregar los elementos de una matriz a otra, así que intenté esto:
[1,2] + [3,4]
Respondió con:
"1,23,4"
Que esta pasando?
[5,6,7][1,2]
es 7
porque usa el último elemento de la segunda matriz. Oo
Respuestas:
El +
operador no está definido para matrices .
Lo que sucede es que Javascript convierte las matrices en cadenas y las concatena.
Desde esta pregunta y, en consecuencia, mi respuesta está recibiendo mucha atención, sentí que sería útil y relevante tener una visión general sobre cómo se +
comporta el operador en general también.
Entonces, aquí va.
Excluyendo E4X y cosas específicas de implementación, Javascript (a partir de ES5) tiene 6 tipos de datos integrados :
Tenga en cuenta que, aunque resulta un typeof
tanto confuso object
para Null y function
para Objetos invocables, Null en realidad no es un Objeto y, estrictamente hablando, en las implementaciones de JavaScript que cumplen con las especificaciones, todas las funciones se consideran Objetos.
Así es: Javascript no tiene matrices primitivas como tales; solo casos de un Objeto llamado Array
con un poco de azúcar sintáctica para aliviar el dolor.
Agregando más a la confusión, las entidades de contenedor como new Number(5)
, new Boolean(true)
y new String("abc")
son todas de object
tipo, no números, booleanos o cadenas como cabría esperar. Sin embargo para operadores aritméticos Number
y se Boolean
comportan como números.
Fácil, ¿eh? Con todo eso fuera del camino, podemos pasar a la visión general en sí.
Diferentes tipos de resultados por tipo de +
operando
|| undefined | null | boolean | number | string | object |
=========================================================================
undefined || number | number | number | number | string | string |
null || number | number | number | number | string | string |
boolean || number | number | number | number | string | string |
number || number | number | number | number | string | string |
string || string | string | string | string | string | string |
object || string | string | string | string | string | string |
* se aplica a Chrome13, FF6, Opera11 e IE9. La comprobación de otros navegadores y versiones se deja como ejercicio para el lector.
Nota: Como se ha señalado por la CMS , para ciertos casos de objetos tales como Number
, Boolean
y los personalizados del +
operador no necesariamente producir un resultado cadena. Puede variar según la implementación del objeto a la conversión primitiva. Por ejemplo, var o = { valueOf:function () { return 4; } };
evaluar o + 2;
produce 6
, a number
, evaluar o + '2'
produce '42'
, a string
.
Para ver cómo se generó la tabla de resumen, visite http://jsfiddle.net/1obxuc7m/
El +
operador de JavaScript tiene dos propósitos: agregar dos números o unir dos cadenas. No tiene un comportamiento específico para las matrices, por lo que las convierte en cadenas y luego las une.
Si desea unir dos matrices para producir una nueva, utilice el .concat
método en su lugar:
[1, 2].concat([3, 4]) // [1, 2, 3, 4]
Si desea agregar eficientemente todos los elementos de una matriz a otra, debe usar el método .push :
var data = [1, 2];
// ES6+:
data.push(...[3, 4]);
// or legacy:
Array.prototype.push.apply(data, [3, 4]);
// data is now [1, 2, 3, 4]
El comportamiento del +
operador se define en ECMA-262 5e Sección 11.6.1 :
11.6.1 El operador de adición (+)
El operador de suma realiza la concatenación de cadenas o la suma numérica. La producción
AdditiveExpression : AdditiveExpression + MultiplicativeExpression
se evalúa de la siguiente manera:
- Dejar
lref
ser el resultado de evaluarAdditiveExpression
.- Dejar que
lval
seaGetValue(lref)
.- Dejar
rref
ser el resultado de evaluarMultiplicativeExpression
.- Dejar que
rval
seaGetValue(rref)
.- Dejar que
lprim
seaToPrimitive(lval)
.- Dejar que
rprim
seaToPrimitive(rval)
.- Si
Type(lprim)
esString
oType(rprim)
esString
, entonces
- Devuelve la cadena que es el resultado de la concatenación
ToString(lprim)
seguida deToString(rprim)
- Devuelve el resultado de aplicar la operación de suma a
ToNumber(lprim)
yToNumber(rprim)
. Ver la Nota a continuación 11.6.3.
Puede ver que cada operando se convierte ToPrimitive
. Al leer más, podemos encontrar que ToPrimitive
siempre convertirá matrices en cadenas, produciendo este resultado.
Array.prototype.push.apply(data, [3, 4])
lugar de data.concat([3,4])
?
concat
produce una nueva matriz, la llamada más larga extiende eficientemente una matriz existente .
[].push.apply(data, [3,4])
para un poco menos de verbosidad. Además, se garantiza que será resistente a que otras personas cambien el valor de Array
.
Agrega las dos matrices como si fueran cadenas .
La representación de cadena para la primera matriz sería "1,2" y la segunda sería "3,4" . Entonces, cuando +
se encuentra el signo, no puede sumar matrices y luego concatenarlas como cadenas.
Las +
cadenas concats, lo que convierte a las matrices de cadenas.
[1,2] + [3,4]
'1,2' + '3,4'
1,23,4
Para combinar matrices, use concat
.
[1,2].concat([3,4])
[1,2,3,4]
En JavaScript, el operador de suma binaria ( +
) realiza la suma numérica y la concatenación de cadenas. Sin embargo, cuando su primer argumento no es ni un número ni una cadena, lo convierte en una cadena (por lo tanto, " 1,2
") y luego hace lo mismo con el segundo " 3,4
" y los concatena en " 1,23,4
".
Intente utilizar el método "concat" de matrices en su lugar:
var a = [1, 2];
var b = [3, 4];
a.concat(b) ; // => [1, 2, 3, 4];
Parece que JavaScript está convirtiendo sus matrices en cadenas y uniéndolas. Si desea agregar tuplas juntas, deberá usar un bucle o una función de mapa.
[1,2]+[3,4]
en JavaScript es lo mismo que evaluar:
new Array( [1,2] ).toString() + new Array( [3,4] ).toString();
y para resolver su problema, lo mejor sería agregar dos matrices en el lugar o sin crear una nueva matriz:
var a=[1,2];
var b=[3,4];
a.push.apply(a, b);
Está haciendo exactamente lo que le pediste que hiciera.
Lo que está agregando son referencias de matriz (que JS convierte en cadenas), no números como parece. Es un poco como agregar cadenas juntas: "hello " + "world"
="hello world"
Sería bueno si pudiera sobrecargar operadores en JavaScript pero no puede: ¿Puedo definir sobrecargas de operadores personalizadas en Javascript? solo puedes hackear el operador "==" que convierte a cadenas antes de comparar: http://blogger.xs4all.nl/peterned/archive/2009/04/01/462517.aspx
Es porque, el operador + supone que los operandos son cadenas, si no son números. Por lo tanto, primero los convierte en cadenas y concatena para dar el resultado final, si no es un número. Además, no admite matrices.
Algunas respuestas aquí han explicado cómo '1,23,4'
ocurre la salida inesperada no deseada ( ) y algunas han explicado cómo obtener lo que suponen que es la salida deseada esperada ( [1,2,3,4]
), es decir, la concatenación de matriz. Sin embargo, la naturaleza del resultado deseado esperado es en realidad algo ambiguo porque la pregunta original simplemente dice "Quería agregar los elementos de una matriz a otra ...". Eso podría significar array concatenación pero podría también Además media tupla (por ejemplo, aquí y aquí ), es decir la adición de los valores escalares de elementos en una matriz a los valores escalares de los elementos correspondientes en el segundo, por ejemplo, combinando [1,2]
y [3,4]
obtener [4,6]
.
Suponiendo que ambas matrices tienen la misma aridad / longitud, aquí hay una solución simple:
const arr1 = [1, 2];
const arr2 = [3, 4];
const add = (a1, a2) => a1.map((e, i) => e + a2[i]);
console.log(add(arr1, arr2)); // ==> [4, 6]