Eu queria adicionar os elementos de uma matriz em outra, então tentei o seguinte:
[1,2] + [3,4]
Respondeu com:
"1,23,4"
O que está acontecendo?
[5,6,7][1,2]é 7porque ele usa o último item na segunda matriz. Oo
Eu queria adicionar os elementos de uma matriz em outra, então tentei o seguinte:
[1,2] + [3,4]
Respondeu com:
"1,23,4"
O que está acontecendo?
[5,6,7][1,2]é 7porque ele usa o último item na segunda matriz. Oo
Respostas:
O +operador não está definido para matrizes .
O que acontece é que o Javascript converte matrizes em seqüências de caracteres e concatena essas.
Como essa pergunta e, consequentemente, minha resposta está recebendo muita atenção, senti que seria útil e relevante ter uma visão geral sobre como o +operador também se comporta em geral.
Então, aqui vai.
Excluindo E4X e outras coisas específicas de implementação, Javascript (a partir de ES5) tem 6 built-in tipos de dados :
Observe que, embora typeof um pouco confuso retorne object para Null e functionpara objetos que podem ser chamados, Null na verdade não é um Object e, estritamente falando, nas implementações Javascript em conformidade com as especificações, todas as funções são consideradas objetos.
Isso mesmo - o Javascript não possui matrizes primitivas ; apenas instâncias de um objeto chamado Arraycom um pouco de açúcar sintático para aliviar a dor.
Adicionando mais à confusão, as entidades do invólucro, como new Number(5), new Boolean(true)e new String("abc")são do objecttipo, não são números, booleanos ou seqüências de caracteres, como seria de esperar. No entanto, para operadores aritméticos Numbere Booleanse comportam como números.
Calma, né? Com tudo isso fora do caminho, podemos avançar para a própria visão geral.
Diferentes tipos de resultado por tipos 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 |
* aplica-se ao Chrome13, FF6, Opera11 e IE9. A verificação de outros navegadores e versões é deixada como um exercício para o leitor.
Nota: Como apontado por CMS , em determinados casos de objectos, tais como Number, Booleane os personalizados do +operador não necessariamente produzir um resultado string. Pode variar dependendo da implementação do objeto em conversão primitiva. Por exemplo, var o = { valueOf:function () { return 4; } };avaliar o + 2;produz 6, a number, avaliar o + '2'produz '42', a string.
Para ver como a tabela de visão geral foi gerada, visite http://jsfiddle.net/1obxuc7m/
O +operador do JavaScript tem dois propósitos: adicionar dois números ou unir duas strings. Ele não possui um comportamento específico para matrizes, portanto, é convertê-las em strings e depois juntá-las.
Se você deseja unir duas matrizes para produzir uma nova, use o .concatmétodo :
[1, 2].concat([3, 4]) // [1, 2, 3, 4]
Se você deseja adicionar com eficiência todos os elementos de uma matriz para outra, é necessário usar o 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]
O comportamento do +operador é definido na Seção 11.6.1 do ECMA-262 5e :
11.6.1 O operador Adição (+)
O operador de adição executa concatenação de sequência ou adição numérica. A produção
AdditiveExpression : AdditiveExpression + MultiplicativeExpressioné avaliada da seguinte forma:
- Seja
lrefo resultado da avaliaçãoAdditiveExpression.- Let
lvalbeGetValue(lref).- Seja
rrefo resultado da avaliaçãoMultiplicativeExpression.- Let
rvalbeGetValue(rref).- Let
lprimbeToPrimitive(lval).- Let
rprimbeToPrimitive(rval).- Se
Type(lprim)éStringouType(rprim)éString, então
- Retorne a String resultante da concatenação
ToString(lprim)seguida porToString(rprim)- Retorne o resultado da aplicação da operação de adição a
ToNumber(lprim)eToNumber(rprim). Veja a nota abaixo 11.6.3.
Você pode ver que cada operando é convertido ToPrimitive. Lendo mais adiante, podemos descobrir que ToPrimitivesempre converterá matrizes em strings, produzindo esse resultado.
Array.prototype.push.apply(data, [3, 4])vez de data.concat([3,4])?
concatproduz uma nova matriz, a chamada mais longa estende com eficiência uma matriz existente .
[].push.apply(data, [3,4])para um pouco menos de verbosidade. Além disso, isso garante resistência a outras pessoas que alteram o valor de Array.
Ele adiciona as duas matrizes como se fossem strings .
A representação de string para a primeira matriz seria "1,2" e a segunda seria "3,4" . Portanto, quando o +sinal é encontrado, ele não pode somar matrizes e concatená-las como strings.
O +concats strings, portanto, converte as matrizes em strings.
[1,2] + [3,4]
'1,2' + '3,4'
1,23,4
Para combinar matrizes, use concat.
[1,2].concat([3,4])
[1,2,3,4]
Em JavaScript, o operador de adição binária ( +) executa adição numérica e concatenação de cadeias. No entanto, quando o primeiro argumento não é um número nem uma string, ele é convertido em uma string (portanto, " 1,2"), então ele faz o mesmo com o segundo " 3,4" e os concatena em " 1,23,4".
Tente usar o método "concat" de matrizes:
var a = [1, 2];
var b = [3, 4];
a.concat(b) ; // => [1, 2, 3, 4];
Parece que o JavaScript está transformando suas matrizes em strings e juntando-as. Se você deseja adicionar tuplas, precisará usar um loop ou uma função de mapa.
[1,2]+[3,4] em JavaScript é o mesmo que avaliar:
new Array( [1,2] ).toString() + new Array( [3,4] ).toString();
e, para resolver seu problema, o melhor seria adicionar duas matrizes no local ou sem criar uma nova matriz:
var a=[1,2];
var b=[3,4];
a.push.apply(a, b);
Está fazendo exatamente o que você pediu.
O que você está adicionando são referências de matriz (que JS converte em strings), não números como parece. É como adicionar cordas: "hello " + "world"="hello world"
seria bom se você pudesse sobrecarregar os operadores em JavaScript, mas não puder: Posso definir sobrecargas personalizadas do operador em Javascript? você pode hackear apenas o operador "==" que converte em cadeias antes de comparar: http://blogger.xs4all.nl/peterned/archive/2009/04/01/462517.aspx
Isso ocorre porque, operador + assume que os operandos são string, se não forem números. Portanto, primeiro os converte em string e concats para fornecer o resultado final, se não for um número. Além disso, ele não suporta matrizes.
Algumas respostas aqui explicaram como a saída indesejada inesperada ( '1,23,4') acontece e algumas explicaram como obter o que elas assumem ser a saída desejada desejada ( [1,2,3,4]), ou seja, concatenação de matriz. No entanto, a natureza do resultado esperado esperado é realmente um tanto ambígua, porque a pergunta original simplesmente declara "eu queria adicionar os elementos de uma matriz em outra ...". Isso pode significar concatenação de matriz, mas também adição de tupla (por exemplo, aqui e aqui ), ou seja, adicionar os valores escalares de elementos em uma matriz aos valores escalares dos elementos correspondentes na segunda, por exemplo, combinar [1,2]e [3,4]obter [4,6].
Supondo que ambas as matrizes tenham a mesma área / comprimento, aqui está uma solução simples:
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]