From d605c504edb3a9e7f7ccf76a4e039975e6b025ab Mon Sep 17 00:00:00 2001 From: odsantos Date: Sun, 9 Feb 2020 23:27:09 +0100 Subject: [PATCH 1/8] Add translation to 'Array' folder files --- .../04-array/1-item-value/solution.md | 6 +- .../04-array/1-item-value/task.md | 13 +- .../10-maximal-subarray/_js.view/test.js | 18 +- .../04-array/10-maximal-subarray/solution.md | 44 +-- .../04-array/10-maximal-subarray/task.md | 20 +- .../04-array/2-create-array/solution.md | 3 +- .../04-array/2-create-array/task.md | 24 +- .../04-array/3-call-array-this/solution.md | 8 +- .../04-array/3-call-array-this/task.md | 7 +- .../04-array/5-array-input-sum/solution.md | 9 +- .../04-array/5-array-input-sum/task.md | 14 +- 1-js/05-data-types/04-array/article.md | 371 +++++++++--------- 12 files changed, 264 insertions(+), 273 deletions(-) diff --git a/1-js/05-data-types/04-array/1-item-value/solution.md b/1-js/05-data-types/04-array/1-item-value/solution.md index e631f1c70..1c80ccff7 100644 --- a/1-js/05-data-types/04-array/1-item-value/solution.md +++ b/1-js/05-data-types/04-array/1-item-value/solution.md @@ -1,8 +1,8 @@ -The result is `4`: +O resultado é `4`: ```js run -let fruits = ["Apples", "Pear", "Orange"]; +let fruits = ["Maçã", "Pêra", "Laranja"]; let shoppingCart = fruits; @@ -13,5 +13,5 @@ alert( fruits.length ); // 4 */!* ``` -That's because arrays are objects. So both `shoppingCart` and `fruits` are the references to the same array. +Isto, porque *arrays* são objetos. Assim ambas `shoppingCart` e `fruits` são referências para o mesmo *array*. diff --git a/1-js/05-data-types/04-array/1-item-value/task.md b/1-js/05-data-types/04-array/1-item-value/task.md index 4fcf384fb..4b2cdce05 100644 --- a/1-js/05-data-types/04-array/1-item-value/task.md +++ b/1-js/05-data-types/04-array/1-item-value/task.md @@ -1,19 +1,18 @@ -importance: 3 +importância: 3 --- -# Is array copied? +# Foi o *array* copiado? -What is this code going to show? +O que irá mostrar este código? ```js -let fruits = ["Apples", "Pear", "Orange"]; +let fruits = ["Maçã", "Pêra", "Laranja"]; -// push a new value into the "copy" +// adicione um novo valor à "cópia" let shoppingCart = fruits; shoppingCart.push("Banana"); -// what's in fruits? +// o que existe em fruits? alert( fruits.length ); // ? ``` - diff --git a/1-js/05-data-types/04-array/10-maximal-subarray/_js.view/test.js b/1-js/05-data-types/04-array/10-maximal-subarray/_js.view/test.js index b44e76fe7..2fbd0dada 100644 --- a/1-js/05-data-types/04-array/10-maximal-subarray/_js.view/test.js +++ b/1-js/05-data-types/04-array/10-maximal-subarray/_js.view/test.js @@ -1,37 +1,37 @@ describe("getMaxSubSum", function() { - it("maximal subsum of [1, 2, 3] equals 6", function() { + it("máxima subsoma de [1, 2, 3] igual a 6", function() { assert.equal(getMaxSubSum([1, 2, 3]), 6); }); - it("maximal subsum of [-1, 2, 3, -9] equals 5", function() { + it("máxima subsoma de [-1, 2, 3, -9] igual a 5", function() { assert.equal(getMaxSubSum([-1, 2, 3, -9]), 5); }); - it("maximal subsum of [-1, 2, 3, -9, 11] equals 11", function() { + it("máxima subsoma de [-1, 2, 3, -9, 11] igual a 11", function() { assert.equal(getMaxSubSum([-1, 2, 3, -9, 11]), 11); }); - it("maximal subsum of [-2, -1, 1, 2] equals 3", function() { + it("máxima subsoma de [-2, -1, 1, 2] igual a 3", function() { assert.equal(getMaxSubSum([-2, -1, 1, 2]), 3); }); - it("maximal subsum of [100, -9, 2, -3, 5] equals 100", function() { + it("máxima subsoma de [100, -9, 2, -3, 5] igual a 100", function() { assert.equal(getMaxSubSum([100, -9, 2, -3, 5]), 100); }); - it("maximal subsum of [] equals 0", function() { + it("máxima subsoma de [] igual a 0", function() { assert.equal(getMaxSubSum([]), 0); }); - it("maximal subsum of [-1] equals 0", function() { + it("máxima subsoma de [-1] igual a 0", function() { assert.equal(getMaxSubSum([-1]), 0); }); - it("maximal subsum of [-1, -2] equals 0", function() { + it("máxima subsoma de [-1, -2] igual a 0", function() { assert.equal(getMaxSubSum([-1, -2]), 0); }); - it("maximal subsum of [2, -8, 5, -1, 2, -3, 2] equals 6", function() { + it("máxima subsoma de [2, -8, 5, -1, 2, -3, 2] igual a 6", function() { assert.equal(getMaxSubSum([2, -8, 5, -1, 2, -3, 2]), 6); }); }); diff --git a/1-js/05-data-types/04-array/10-maximal-subarray/solution.md b/1-js/05-data-types/04-array/10-maximal-subarray/solution.md index daadf494b..61a9fc9e8 100644 --- a/1-js/05-data-types/04-array/10-maximal-subarray/solution.md +++ b/1-js/05-data-types/04-array/10-maximal-subarray/solution.md @@ -1,43 +1,43 @@ -# Slow solution +# Solução lenta -We can calculate all possible subsums. +Nós podemos calcular todas as possíveis subsomas. -The simplest way is to take every element and calculate sums of all subarrays starting from it. +A forma mais simples será tomar cada elemento e calcular as somas de todos os *subarrays* que comecem por ele. -For instance, for `[-1, 2, 3, -9, 11]`: +Por exemplo, para `[-1, 2, 3, -9, 11]`: ```js no-beautify -// Starting from -1: +// Começando por -1: -1 -1 + 2 -1 + 2 + 3 -1 + 2 + 3 + (-9) -1 + 2 + 3 + (-9) + 11 -// Starting from 2: +// Começando por 2: 2 2 + 3 2 + 3 + (-9) 2 + 3 + (-9) + 11 -// Starting from 3: +// Começando por 3: 3 3 + (-9) 3 + (-9) + 11 -// Starting from -9 +// Começando por -9 -9 -9 + 11 -// Starting from 11 +// Começando por 11 11 ``` -The code is actually a nested loop: the external loop over array elements, and the internal counts subsums starting with the current element. +Na verdade, o código é um laço aninhado (*nested loop*): o externo percorre os elementos do *array*, e o interno calcula as subsomas que comecem pelo elemento atual. ```js run function getMaxSubSum(arr) { - let maxSum = 0; // if we take no elements, zero will be returned + let maxSum = 0; // se não tomarmos nenhum elemento, zero será retornado for (let i = 0; i < arr.length; i++) { let sumFixedStart = 0; @@ -57,25 +57,25 @@ alert( getMaxSubSum([1, 2, 3]) ); // 6 alert( getMaxSubSum([100, -9, 2, -3, 5]) ); // 100 ``` -The solution has a time complexety of [O(n2)](https://en.wikipedia.org/wiki/Big_O_notation). In other words, if we increase the array size 2 times, the algorithm will work 4 times longer. +A solução tem um tempo de complexidade de [O(n2)](https://en.wikipedia.org/wiki/Big_O_notation). Por outras palavras, se aumentarmos o tamanho do *array* para o dobro, o algoritmo demorará 4 vezes mais. -For big arrays (1000, 10000 or more items) such algorithms can lead to a serious sluggishness. +Para grandes *arrays* (1000, 10000 ou mais itens) tais algoritmos podem levar a sérias lentidões. -# Fast solution +# Solução rápida -Let's walk the array and keep the current partial sum of elements in the variable `s`. If `s` becomes negative at some point, then assign `s=0`. The maximum of all such `s` will be the answer. +Vamos percorrer o *array* e guardar a atual soma partial dos elementos na variável `s`. Se, a certa altura, `s` se tornar negativo, então faça a atribuição `s=0`. O máximo desses `s` será a resposta. -If the description is too vague, please see the code, it's short enough: +Se, a descrição for demasiado vaga, por favor veja o código; é realmente curto: ```js run demo function getMaxSubSum(arr) { let maxSum = 0; let partialSum = 0; - for (let item of arr) { // for each item of arr - partialSum += item; // add it to partialSum - maxSum = Math.max(maxSum, partialSum); // remember the maximum - if (partialSum < 0) partialSum = 0; // zero if negative + for (let item of arr) { // por cada item de arr + partialSum += item; // o adicione a partialSum ('s' na descrição) + maxSum = Math.max(maxSum, partialSum); // guarde o máximo + if (partialSum < 0) partialSum = 0; // zero se negativo } return maxSum; @@ -89,6 +89,6 @@ alert( getMaxSubSum([1, 2, 3]) ); // 6 alert( getMaxSubSum([-1, -2, -3]) ); // 0 ``` -The algorithm requires exactly 1 array pass, so the time complexity is O(n). +O algoritmo requere exatamente 1 passagem sobre o *array*, portanto o tempo de complexidade é O(n). -You can find more detail information about the algorithm here: [Maximum subarray problem](http://en.wikipedia.org/wiki/Maximum_subarray_problem). If it's still not obvious why that works, then please trace the algorithm on the examples above, see how it works, that's better than any words. +Pode encontrar informação mais detalhada sobre o algoritmo aqui: [Sublista contígua de soma máxima](https://pt.wikipedia.org/wiki/Sublista_cont%C3%ADgua_de_soma_m%C3%A1xima). Se, ainda não for óbvio como isso funciona, então por favor percorra cada algoritmo nos exemplos acima e veja como trabalha, é melhor do que quaisquer palavras. diff --git a/1-js/05-data-types/04-array/10-maximal-subarray/task.md b/1-js/05-data-types/04-array/10-maximal-subarray/task.md index e63c4e625..ed3badf3f 100644 --- a/1-js/05-data-types/04-array/10-maximal-subarray/task.md +++ b/1-js/05-data-types/04-array/10-maximal-subarray/task.md @@ -1,30 +1,30 @@ -importance: 2 +importância: 2 --- -# A maximal subarray +# Um máximo *subarray* -The input is an array of numbers, e.g. `arr = [1, -2, 3, 4, -9, 6]`. +A entrada é um *array* de números, ex. `arr = [1, -2, 3, 4, -9, 6]`. -The task is: find the contiguous subarray of `arr` with the maximal sum of items. +A tarefa é: encontrar o contíguo *subarray* de `arr` com a máxima soma de itens. -Write the function `getMaxSubSum(arr)` that will return that sum. +Escreva a função `getMaxSubSum(arr)` que irá retornar essa soma. -For instance: +Por exemplo: ```js -getMaxSubSum([-1, *!*2, 3*/!*, -9]) = 5 (the sum of highlighted items) +getMaxSubSum([-1, *!*2, 3*/!*, -9]) = 5 (a soma dos itens em destaque) getMaxSubSum([*!*2, -1, 2, 3*/!*, -9]) = 6 getMaxSubSum([-1, 2, 3, -9, *!*11*/!*]) = 11 getMaxSubSum([-2, -1, *!*1, 2*/!*]) = 3 getMaxSubSum([*!*100*/!*, -9, 2, -3, 5]) = 100 -getMaxSubSum([*!*1, 2, 3*/!*]) = 6 (take all) +getMaxSubSum([*!*1, 2, 3*/!*]) = 6 (tome todos) ``` -If all items are negative, it means that we take none (the subarray is empty), so the sum is zero: +Se todos os itens forem negativos, significa que não tomamos nenhum (o *subarray* está vazio), então a soma é zero: ```js getMaxSubSum([-1, -2, -3]) = 0 ``` -Please try to think of a fast solution: [O(n2)](https://en.wikipedia.org/wiki/Big_O_notation) or even O(n) if you can. +Por favor, tente pensar numa solução rápida: [O(n2)](https://en.wikipedia.org/wiki/Big_O_notation), ou mesmo O(n) se puder. diff --git a/1-js/05-data-types/04-array/2-create-array/solution.md b/1-js/05-data-types/04-array/2-create-array/solution.md index f032b55f0..b9e7c5a2e 100644 --- a/1-js/05-data-types/04-array/2-create-array/solution.md +++ b/1-js/05-data-types/04-array/2-create-array/solution.md @@ -3,8 +3,7 @@ ```js run let styles = ["Jazz", "Blues"]; styles.push("Rock-n-Roll"); -styles[Math.floor((styles.length - 1) / 2)] = "Classics"; +styles[Math.floor((styles.length - 1) / 2)] = "Clássicos"; alert( styles.shift() ); styles.unshift("Rap", "Reggae"); ``` - diff --git a/1-js/05-data-types/04-array/2-create-array/task.md b/1-js/05-data-types/04-array/2-create-array/task.md index 3e9300793..9f37f0cbe 100644 --- a/1-js/05-data-types/04-array/2-create-array/task.md +++ b/1-js/05-data-types/04-array/2-create-array/task.md @@ -1,24 +1,24 @@ -importance: 5 +importância: 5 --- -# Array operations. +# Operações com *arrays*. -Let's try 5 array operations. +Vamos tentar 5 operações com *arrays*. -1. Create an array `styles` with items "Jazz" and "Blues". -2. Append "Rock-n-Roll" to the end. -3. Replace the value in the middle by "Classics". Your code for finding the middle value should work for any arrays with odd length. -4. Strip off the first value of the array and show it. -5. Prepend `Rap` and `Reggae` to the array. +1. Crie um *array* `styles` com os itens "Jazz" e "Blues". +2. Adicione "Rock-n-Roll" ao fim. +3. Substitua o valor do meio por "Clássicos". O seu código para encontrar o valor do meio deverá funcionar para quaisquer *arrays* com um comprimento ímpar. +4. Elimine o primeiro valor do *array* e o mostre. +5. Adicione `Rap` e `Reggae` ao inicio do *array*. -The array in the process: +O *array* ao longo do processo: ```js no-beautify Jazz, Blues Jazz, Bues, Rock-n-Roll -Jazz, Classics, Rock-n-Roll -Classics, Rock-n-Roll -Rap, Reggae, Classics, Rock-n-Roll +Jazz, Clássicos, Rock-n-Roll +Clássicos, Rock-n-Roll +Rap, Reggae, Clássicos, Rock-n-Roll ``` diff --git a/1-js/05-data-types/04-array/3-call-array-this/solution.md b/1-js/05-data-types/04-array/3-call-array-this/solution.md index e994ae078..ce5450b56 100644 --- a/1-js/05-data-types/04-array/3-call-array-this/solution.md +++ b/1-js/05-data-types/04-array/3-call-array-this/solution.md @@ -1,6 +1,6 @@ -The call `arr[2]()` is syntactically the good old `obj[method]()`, in the role of `obj` we have `arr`, and in the role of `method` we have `2`. +A invocação `arr[2]()` é sintáticamente a antiga `obj[method]()`; no papel de `obj` temos `arr`, e no papel de `method` temos `2`. -So we have a call of the function `arr[2]` as an object method. Naturally, it receives `this` referencing the object `arr` and outputs the array: +Assim, temos uma chamada da função `arr[2]` como um método de objeto. Naturalmente, como ela recebe em `this` a referência ao objeto `arr`, ela mostra como saída o *array*: ```js run let arr = ["a", "b"]; @@ -9,7 +9,7 @@ arr.push(function() { alert( this ); }) -arr[2](); // "a","b",function +arr[2](); // "a","b", function ``` -The array has 3 values: initially it had two, plus the function. +O *array* tem 3 valores: os dois inicias, mais a função. diff --git a/1-js/05-data-types/04-array/3-call-array-this/task.md b/1-js/05-data-types/04-array/3-call-array-this/task.md index 340c5feef..43f143716 100644 --- a/1-js/05-data-types/04-array/3-call-array-this/task.md +++ b/1-js/05-data-types/04-array/3-call-array-this/task.md @@ -1,10 +1,10 @@ -importance: 5 +importância: 5 --- -# Calling in an array context +# Invocando o contexto de um *array* -What is the result? Why? +Qual é o resultado? Porquê? ```js let arr = ["a", "b"]; @@ -15,4 +15,3 @@ arr.push(function() { arr[2](); // ? ``` - diff --git a/1-js/05-data-types/04-array/5-array-input-sum/solution.md b/1-js/05-data-types/04-array/5-array-input-sum/solution.md index 75bd683b5..4695d34fd 100644 --- a/1-js/05-data-types/04-array/5-array-input-sum/solution.md +++ b/1-js/05-data-types/04-array/5-array-input-sum/solution.md @@ -1,4 +1,4 @@ -Please note the subtle, but important detail of the solution. We don't convert `value` to number instantly after `prompt`, because after `value = +value` we would not be able to tell an empty string (stop sign) from the zero (valid number). We do it later instead. +Por favor repare no subtítulo, e em importantes detalhes da solução. Nós não convertemos `value` para número imediatamente após `prompt`, porque depois de `value = +value` não temos como diferenciar uma *string* vazia (sinal para parar) de zero (número válido). Em vez disso, o fazemos mais tarde. ```js run demo @@ -8,9 +8,9 @@ function sumInput() { while (true) { - let value = prompt("A number please?", 0); + let value = prompt("Um número, por favor?", 0); - // should we cancel? + // devemos cancelar? if (value === "" || value === null || !isFinite(value)) break; numbers.push(+value); @@ -23,6 +23,5 @@ function sumInput() { return sum; } -alert( sumInput() ); +alert( sumInput() ); ``` - diff --git a/1-js/05-data-types/04-array/5-array-input-sum/task.md b/1-js/05-data-types/04-array/5-array-input-sum/task.md index 4af8e7c95..c3d6035a1 100644 --- a/1-js/05-data-types/04-array/5-array-input-sum/task.md +++ b/1-js/05-data-types/04-array/5-array-input-sum/task.md @@ -1,15 +1,15 @@ -importance: 4 +importância: 4 --- -# Sum input numbers +# Some números inseridos -Write the function `sumInput()` that: +Escreva a função `sumInput()` que: -- Asks the user for values using `prompt` and stores the values in the array. -- Finishes asking when the user enters a non-numeric value, an empty string, or presses "Cancel". -- Calculates and returns the sum of array items. +- Peça ao utilizador por valores usando `prompt` e guarde os valores num *array*. +- Acabe o pedido quando o utilizador inserir um valor não-numérico, uma *string* vazia, ou pressione "*Cancel*". +- Calcule e retorne a soma dos itens no *array*. -P.S. A zero `0` is a valid number, please don't stop the input on zero. +P.S. Um zero `0` é um número válido, por favor não pare a inserção com zero. [demo] diff --git a/1-js/05-data-types/04-array/article.md b/1-js/05-data-types/04-array/article.md index aead164f5..da39c8cf0 100644 --- a/1-js/05-data-types/04-array/article.md +++ b/1-js/05-data-types/04-array/article.md @@ -1,286 +1,284 @@ -# Arrays +# *Arrays* -Objects allow you to store keyed collections of values. That's fine. +Objetos permitem-lhe armazenar coleções de valores por chaves. É bom. -But quite often we find that we need an *ordered collection*, where we have a 1st, a 2nd, a 3rd element and so on. For example, we need that to store a list of something: users, goods, HTML elements etc. +Mas, frequentemente precisamos de uma *coleção ordenada*, onde tenhamos um 1º, 2º, 3º elemento e assim por diante. Por exemplo, precisamos dela para armazenar uma lista de algo como: visitantes, bens, elementos de HTML, etc. -It is not convenient to use an object here, because it provides no methods to manage the order of elements. We can’t insert a new property “between” the existing ones. Objects are just not meant for such use. +Não é conveniente usar um objeto aqui, porque ele não dispõe de métodos para gerir a ordem dos elementos. Não podemos inserir uma nova propriedade “entre” outras já existentes. Objetos simplesmente não são adequados a tal uso. -There exists a special data structure named `Array`, to store ordered collections. +Existe uma estrutura de dados especial chamada `Array`, para armazenar coleções ordenadas. -## Declaration +## Declaração -There are two syntaxes for creating an empty array: +Existem duas sintaxes para criar um *array* vazio: ```js let arr = new Array(); let arr = []; ``` -Almost all the time, the second syntax is used. We can supply initial elements in the brackets: +Quase sempre é usada a segunda sintaxe. Podemos fornecer elementos iniciais entre os parênteses: ```js -let fruits = ["Apple", "Orange", "Plum"]; +let fruits = ["Maçã", "Laranja", "Ameixa"]; ``` -Array elements are numbered, starting with zero. +Os elementos de um *array* são numerados, começando por zero. -We can get an element by its number in square brackets: +Podemos obter um elemento por meio do seu número entre parênteses retos: ```js run -let fruits = ["Apple", "Orange", "Plum"]; +let fruits = ["Maçã", "Laranja", "Ameixa"]; -alert( fruits[0] ); // Apple -alert( fruits[1] ); // Orange -alert( fruits[2] ); // Plum +alert( fruits[0] ); // Maçã +alert( fruits[1] ); // Laranja +alert( fruits[2] ); // Ameixa ``` -We can replace an element: +Podemos substituir um elemento: ```js -fruits[2] = 'Pear'; // now ["Apple", "Orange", "Pear"] +fruits[2] = 'Pêra'; // now ["Maçã", "Laranja", "Pêra"] ``` -...Or add a new one to the array: +...Ou adicionar um novo ao *array*: ```js -fruits[3] = 'Lemon'; // now ["Apple", "Orange", "Pear", "Lemon"] +fruits[3] = 'Limão'; // now ["Maçã", "Laranja", "Pêra", "Limão"] ``` -The total count of the elements in the array is its `length`: +A contagem total dos elementos no *array* é o seu `*length*` (comprimento): ```js run -let fruits = ["Apple", "Orange", "Plum"]; +let fruits = ["Maçã", "Laranja", "Ameixa"]; alert( fruits.length ); // 3 ``` -We can also use `alert` to show the whole array. +Podemos também utilizar `alert` para mostrar todo o *array*. ```js run -let fruits = ["Apple", "Orange", "Plum"]; +let fruits = ["Maçã", "Laranja", "Ameixa"]; -alert( fruits ); // Apple,Orange,Plum +alert( fruits ); // Maçã,Laranja,Ameixa ``` -An array can store elements of any type. +Um *array* pode armazenar elementos de qualquer tipo. -For instance: +Por exemplo: ```js run no-beautify -// mix of values -let arr = [ 'Apple', { name: 'John' }, true, function() { alert('hello'); } ]; +// mistura de valores +let arr = [ 'Maçã', { name: 'John' }, true, function() { alert('olá'); } ]; -// get the object at index 1 and then show its name +// obtenha o objeto no índice 1 e a seguir mostre o seu nome alert( arr[1].name ); // John -// get the function at index 3 and run it -arr[3](); // hello +// obtenha a função no índice 3 e a execute +arr[3](); // olá ``` -````smart header="Trailing comma" -An array, just like an object, may end with a comma: -```js +````smart header="Vírgula final" +Um array, tal como um objeto, pode terminar por uma vírgula: +```js let fruits = [ - "Apple", - "Orange", - "Plum"*!*,*/!* + "Maçã", + "Laranja", + "Ameixa"*!*,*/!* ]; ``` -The "trailing comma" style makes it easier to insert/remove items, because all lines become alike. +O estilo de "vírgula final" torna mais fácil inserir/remover itens, porque todas as linhas se tornam semelhantes. ```` +## Métodos pop/push, shift/unshift -## Methods pop/push, shift/unshift - -A [queue](https://en.wikipedia.org/wiki/Queue_(abstract_data_type)) is one of most common uses of an array. In computer science, this means an ordered collection of elements which supports two operations: +Uma [fila](https://pt.wikipedia.org/wiki/FIFO) (*queue*) é um dos usos mais comuns de um *array*. Em ciência dos computadores, isto significa uma coleção ordenada de elementos que suporta duas operações: -- `push` appends an element to the end. -- `shift` get an element from the beginning, advancing the queue, so that the 2nd element becomes the 1st. +- `push` adiciona um elemento ao final. +- `shift` obtem um elemento do início, avançando a fila, de modo que o 2º elemento se torne no 1º. ![](queue.svg) -Arrays support both operations. +Os *arrays* suportam ambas as operações. -In practice we need it very often. For example, a queue of messages that need to be shown on-screen. +Na prática, nós as precisamos frequentemente. Por exemplo, uma fila de mensagens que precise de ser mostrada no ecrâ. -There's another use case for arrays -- the data structure named [stack](https://en.wikipedia.org/wiki/Stack_(abstract_data_type)). +Existe um outro caso prático para *arrays* -- a estrutura de dados chamada [pilha](https://pt.wikipedia.org/wiki/Pilha_(inform%C3%A1tica)) (stack). -It supports two operations: +Ela suporta duas operações: -- `push` adds an element to the end. -- `pop` takes an element from the end. +- `push` adiciona um elemento ao final. +- `pop` toma um elemento do final. -So new elements are added or taken always from the "end". +Assim, novos elementos são adicionados ou tomados sempre a partir do "final". -A stack is usually illustrated as a pack of cards: new cards are added to the top or taken from the top: +Uma pilha (*stack*) é geralmente ilustrada como um baralho de cartas: novas cartas são adicionadas ao topo ou tiradas do topo: ![](stack.svg) -For stacks, the latest pushed item is received first, that's also called LIFO (Last-In-First-Out) principle. For queues, we have FIFO (First-In-First-Out). - -Arrays in JavaScript can work both as a queue and as a stack. They allow you to add/remove elements both to/from the beginning or the end. +Para pilhas (*stacks*), o último item inserido é recebido primeiro, o que também é chamado de princípio *LIFO* (*Last-In-First-Out*) [o-Último-a-Entrar-é-o-Primeiro-a-Sair]. Para filas (*queues*), nós temos *FIFO* (*First-In-First-Out*) [o-Primeiro-a-Entrar-é-o-Primeiro-a-Sair]. +Os *arrays* em JavaScript podem funcionar tanto como uma fila, como uma pilha. Eles permitem-lhe adicionar/remover elementos quer ao/do início como ao/do final. -In computer science the data structure that allows it is called [deque](https://en.wikipedia.org/wiki/Double-ended_queue). +Em ciência dos computadores, a estrutura de dados que o permite é chamada [deque](https://pt.wikipedia.org/wiki/Deque_(estruturas_de_dados)). -**Methods that work with the end of the array:** +**Métodos que trabalham no final do _array_:** -`pop` -: Extracts the last element of the array and returns it: +`*pop*` +: Extrai o último elemento do *array* e o retorna: ```js run - let fruits = ["Apple", "Orange", "Pear"]; + let fruits = ["Maçã", "Laranja", "Pêra"]; - alert( fruits.pop() ); // remove "Pear" and alert it + alert( fruits.pop() ); // remove "Pêra" e o exibe - alert( fruits ); // Apple, Orange + alert( fruits ); // Maçã, Laranja ``` -`push` -: Append the element to the end of the array: +`*push*` +: Adiciona o elemento ao final do *array*: ```js run - let fruits = ["Apple", "Orange"]; + let fruits = ["Maçã", "Laranja"]; - fruits.push("Pear"); + fruits.push("Pêra"); - alert( fruits ); // Apple, Orange, Pear + alert( fruits ); // Maçã, Laranja, Pêra ``` - The call `fruits.push(...)` is equal to `fruits[fruits.length] = ...`. + A invocação `fruits.push(...)` é igual a `fruits[fruits.length] = ...`. -**Methods that work with the beginning of the array:** +**Métodos que trabalham no início do _array_:** -`shift` -: Extracts the first element of the array and returns it: +`*shift*` +: Extrai o primeiro elemento do *array* e o retorna: ```js - let fruits = ["Apple", "Orange", "Pear"]; + let fruits = ["Maçã", "Laranja", "Pêra"]; - alert( fruits.shift() ); // remove Apple and alert it + alert( fruits.shift() ); // remove Maçã e o exibe - alert( fruits ); // Orange, Pear + alert( fruits ); // Laranja, Pêra ``` -`unshift` -: Add the element to the beginning of the array: +`*unshift*` +: Adiciona o elemento ao início do *array*: ```js - let fruits = ["Orange", "Pear"]; + let fruits = ["Laranja", "Pêra"]; - fruits.unshift('Apple'); + fruits.unshift('Maçã'); - alert( fruits ); // Apple, Orange, Pear + alert( fruits ); // Maçã, Laranja, Pêra ``` -Methods `push` and `unshift` can add multiple elements at once: +Os métodos `*push*` e `*unshift*` podem adicionar múltiplos elementos de uma só vez: ```js run -let fruits = ["Apple"]; +let fruits = ["Maçã"]; -fruits.push("Orange", "Peach"); -fruits.unshift("Pineapple", "Lemon"); +fruits.push("Laranja", "Pêssego"); +fruits.unshift("Ananás", "Limão"); -// ["Pineapple", "Lemon", "Apple", "Orange", "Peach"] +// ["Ananás", "Limão", "Maçã", "Laranja", "Pêssego"] alert( fruits ); ``` -## Internals +## Internamente -An array is a special kind of object. The square brackets used to access a property `arr[0]` actually come from the object syntax. Numbers are used as keys. +Um *array* é um tipo especial de objeto. Os parêntesis retos utilizados para aceder a uma propriedade `arr[0]` vêm, na verdade, da sintaxe de objetos. Números são usados como chaves. -They extend objects providing special methods to work with ordered collections of data and also the `length` property. But at the core it's still an object. +Eles são uma extensão aos objetos, fornecendo métodos especiais para trabalhar com coleções ordenadas de dados e também a propriedade `length`. Assim, no seu núcleo um *array* é um objeto. -Remember, there are only 7 basic types in JavaScript. Array is an object and thus behaves like an object. +Lembre-se, existem apenas 7 tipos básicos em JavaScript. O *array* é um objeto e portanto comporta-se como um objeto. -For instance, it is copied by reference: +Por exemplo, ele é copiado por referência: ```js run let fruits = ["Banana"] -let arr = fruits; // copy by reference (two variables reference the same array) +let arr = fruits; // cópia por referência (duas variáveis referenciam o mesmo array) -alert( arr === fruits ); // true +alert( arr === fruits ); // true (verdadeiro) -arr.push("Pear"); // modify the array by reference +arr.push("Pear"); // modifique o array por referência -alert( fruits ); // Banana, Pear - 2 items now +alert( fruits ); // Banana, Pêra - 2 itens agora ``` -...But what makes arrays really special is their internal representation. The engine tries to store its elements in the contiguous memory area, one after another, just as depicted on the illustrations in this chapter, and there are other optimizations as well, to make arrays work really fast. +...Mas, o que torna *arrays* realmente especiais é a sua representação interna. O interpretador de JavaScript tenta armazenar os seus elementos numa área contígua de memória, um após outro, precisamente como mostrado nas ilustrações deste capítulo, e existem também outras optimizações para fazerem os *arrays* trabalhar verdadeiramente rápido. -But they all break if we quit working with an array as with an "ordered collection" and start working with it as if it were a regular object. +Mas, todas elas quebram se pararmos de trabalhar com um *array* como uma "coleção ordenada", e começarmos a trabalhar com ele como se fosse um objeto regular. -For instance, technically we can do this: +Por exemplo, tecnicamente nós podemos fazer isto: ```js -let fruits = []; // make an array +let fruits = []; // cria um array -fruits[99999] = 5; // assign a property with the index far greater than its length +fruits[99999] = 5; // atribui uma propriedade com um índice muito maior do que o seu comprimento -fruits.age = 25; // create a property with an arbitrary name +fruits.age = 25; // cria uma propriedade com um nome arbitrário ``` -That's possible, because arrays are objects at their base. We can add any properties to them. +Isso é possível, porque *arrays* são objetos na sua base. Podemos adicionar qualquer propriedade a eles. -But the engine will see that we're working with the array as with a regular object. Array-specific optimizations are not suited for such cases and will be turned off, their benefits disappear. +Mas, o interpretador de JavaScript (*JavaSript engine*) verá que nós estamos a trabalhar com o *array* como com um objeto regular. Optimizações especificas para *arrays* não são adequadas a estes casos e serão desativadas, os seus benifícios desaparecem. -The ways to misuse an array: +Formas de má utilização de um *array*: -- Add a non-numeric property like `arr.test = 5`. -- Make holes, like: add `arr[0]` and then `arr[1000]` (and nothing between them). -- Fill the array in the reverse order, like `arr[1000]`, `arr[999]` and so on. +- Adicionar uma propriedade não-numérica como `arr.test = 5`. +- Formar buracos, como: adicionar `arr[0]` e depois `arr[1000]` (e nada entre eles). +- Preencher o *array* por ordem inversa, como `arr[1000]`, `arr[999]` e assim por diante. -Please think of arrays as special structures to work with the *ordered data*. They provide special methods for that. Arrays are carefully tuned inside JavaScript engines to work with contiguous ordered data, please use them this way. And if you need arbitrary keys, chances are high that you actually require a regular object `{}`. +Por favor, pense em *arrays* como estruturas especiais para trabalhar com *dados ordenados*. Eles fornecem métodos especiais para isso. *Arrays* são cuidadosamente afinados dentro dos interpretadores de JavaScript (*JavaScript engines*) para trabalharem com dados ordenados contíguos, por favor os utilize dessa forma. E, se precisar de chaves arbitrárias, são altas as chances de que na verdade necessite de um objeto regular `{}`. ## Performance -Methods `push/pop` run fast, while `shift/unshift` are slow. +Métodos `push/pop` são executados rápidamente, enquanto `shift/unshift` são lentos. ![](array-speed.svg) -Why is it faster to work with the end of an array than with its beginning? Let's see what happens during the execution: +Porque é mais rápido trabalhar no final de um *array*, do que no seu início? Vejamos o que acontece durante a execução: ```js -fruits.shift(); // take 1 element from the start +fruits.shift(); // tome 1 elemento do início ``` -It's not enough to take and remove the element with the number `0`. Other elements need to be renumbered as well. +Não é suficiente tomar e remover o elemento com o número `0`. Os outros elementos também necessitam de ser renumerados. -The `shift` operation must do 3 things: +A operação `shift` deve efetuar 3 coisas: -1. Remove the element with the index `0`. -2. Move all elements to the left, renumber them from the index `1` to `0`, from `2` to `1` and so on. -3. Update the `length` property. +1. Remover o elemento com o indice `0`. +2. Mover todos os elementos para a esquerda, renumerando-os do indice `1` para `0`, do `2` para `1`, e assim por diante. +3. Atualizar a propriedade `length`. ![](array-shift.svg) -**The more elements in the array, the more time to move them, more in-memory operations.** +**Quantos mais elementos no *array*, mais tempo se leva para os mover, e mais operações em memória.** -The similar thing happens with `unshift`: to add an element to the beginning of the array, we need first to move existing elements to the right, increasing their indexes. +À semelhança acontece com `unshift`: para adicionar um elemento ao início do *array*, nós primeiro precisamos de mover os elementos existentes para à direita, e aumentar os seus indices. -And what's with `push/pop`? They do not need to move anything. To extract an element from the end, the `pop` method cleans the index and shortens `length`. +E, o que se passa com `push/pop`? Eles, não precisam de mover nada. Para extrair um elemento do final, o método `pop` elimina o indice e diminui `length`. -The actions for the `pop` operation: +As ações para a operação `pop`: ```js -fruits.pop(); // take 1 element from the end +fruits.pop(); // tome 1 elemento do final ``` ![](array-pop.svg) -**The `pop` method does not need to move anything, because other elements keep their indexes. That's why it's blazingly fast.** +**O método `pop` não precisa de mover nada, porque os outros elementos mantêm os seus indices. É por isso que são extremamente rápidos.** -The similar thing with the `push` method. +O semelhante se passa com o método `push`. -## Loops +## *Loops* -One of the oldest ways to cycle array items is the `for` loop over indexes: +Uma das velhas formas para percorrer itens de um *array*, é através de um ciclo (*loop*) `for` sobre os seus indices: ```js run -let arr = ["Apple", "Orange", "Pear"]; +let arr = ["Maçã", "Laranja", "Pêra"]; *!* for (let i = 0; i < arr.length; i++) { @@ -289,103 +287,102 @@ for (let i = 0; i < arr.length; i++) { } ``` -But for arrays there is another form of loop, `for..of`: +Mas, para *arrays* existe um outro ciclo (*loop*), `for..of`: ```js run -let fruits = ["Apple", "Orange", "Plum"]; +let fruits = ["Maçã", "Laranja", "Ameixa"]; -// iterates over array elements +// itera sobre os elementos do array for (let fruit of fruits) { alert( fruit ); } ``` -The `for..of` doesn't give access to the number of the current element, just its value, but in most cases that's enough. And it's shorter. +O `for..of` não dá acesso ao número do elemento atual, mas apenas ao seu valor, contudo em muitos casos é o suficiente. E a sintaxe é mais curta. -Technically, because arrays are objects, it is also possible to use `for..in`: +Tecnicamente, uma vez que *arrays* são objetos, também é possível usar `for..in`: ```js run -let arr = ["Apple", "Orange", "Pear"]; +let arr = ["Maçã", "Laranja", "Pêra"]; *!* for (let key in arr) { */!* - alert( arr[key] ); // Apple, Orange, Pear + alert( arr[key] ); // Maçã, Laranja, Pêra } ``` -But that's actually a bad idea. There are potential problems with it: +Mas, na verdade é uma má ideia. Existem problemas potenciais com isso: -1. The loop `for..in` iterates over *all properties*, not only the numeric ones. +1. O laço (*loop*) `for..in` itera sobre *todas as propriedades*, não apenas sobre as numéricas. - There are so-called "array-like" objects in the browser and in other environments, that *look like arrays*. That is, they have `length` and indexes properties, but they may also have other non-numeric properties and methods, which we usually don't need. The `for..in` loop will list them though. So if we need to work with array-like objects, then these "extra" properties can become a problem. + Existem os objetos chamados de "semelhantes-a-arrays" (*array-like*), no navegador (*browser*) e em outros ambientes, que *se parecem com _arrays_*. Isto é, eles têm as propriedades `length` (comprimento) e indices, mas também podem ter outras propriedades e métodos não-numéricos, que geralmente não precisamos. Contudo, o laço (*loop*) `for..in` listará todos eles. Assim, se nós precisarmos de trabalhar com objetos semelhantes-a-arrays, aí estas propriedades "extra" podem constituir um problema. -2. The `for..in` loop is optimized for generic objects, not arrays, and thus is 10-100 times slower. Of course, it's still very fast. The speedup may only matter in bottlenecks or seem irrelevant. But still we should be aware of the difference. +2. O laço (*loop*) `for..in` está optimizado para objetos genéricos, não *arrays*, e desta forma é 10-100 mais lento. Contudo, ainda é muito rápido. A velocidade pode apenas ser importante em pontos cruciais (*bottlenecks*), e em caso contrário parecer irrelevante. Mas, ainda assim deveríamos estar de sobreaviso sobre a diferença. -Generally, we shouldn't use `for..in` for arrays. +Em geral, não deveríamos usar `for..in` para *arrays*. +## Uma palavra sobre "comprimento" -## A word about "length" +A propriedade `length` (comprimento) se atualiza automaticamente quando nós modificamos o *array*. Para ser preciso, na verdade ela não é a contagem dos valores no *array*, mas sim o maior indice numérico mais um. -The `length` property automatically updates when we modify the array. To be precise, it is actually not the count of values in the array, but the greatest numeric index plus one. - -For instance, a single element with a large index gives a big length: +Por exemplo, um único elemento com um indice alto produz um comprimento grande: ```js run let fruits = []; -fruits[123] = "Apple"; +fruits[123] = "Maçã"; alert( fruits.length ); // 124 ``` -Note that we usually don't use arrays like that. +Note que geralmente nós não usamos *arrays* dessa forma. -Another interesting thing about the `length` property is that it's writable. +Uma outra coisa interessante sobre a propriedade `length`, é que pode ser alterada. -If we increase it manually, nothing interesting happens. But if we decrease it, the array is truncated. The process is irreversible, here's the example: +Se a aumentarmos manualmente, nada de interessante acontece. Mas, se nós a diminuirmos, o *array* é truncado. O processo é irreversível, e aqui está um exemplo: ```js run let arr = [1, 2, 3, 4, 5]; -arr.length = 2; // truncate to 2 elements +arr.length = 2; // trunque para 2 elementos alert( arr ); // [1, 2] -arr.length = 5; // return length back -alert( arr[3] ); // undefined: the values do not return +arr.length = 5; // retorna o comprimento de volta +alert( arr[3] ); // undefined: os valores não reaparecem ``` -So, the simplest way to clear the array is: `arr.length = 0;`. +Assim, a forma mais simples de limpar um array é: `arr.length = 0;`. -## new Array() [#new-array] +## new Array() [#novo-array] -There is one more syntax to create an array: +Há mais uma sintaxe para se criar um *array*: ```js -let arr = *!*new Array*/!*("Apple", "Pear", "etc"); +let arr = *!*new Array*/!*("Maçã", "Pêra", "etc"); ``` -It's rarely used, because square brackets `[]` are shorter. Also there's a tricky feature with it. +Raramente é usada, porque os parênteses retos são mais curtos `[]`. Além disso, existe uma característica peculiar a acompanhá-la. -If `new Array` is called with a single argument which is a number, then it creates an array *without items, but with the given length*. +Se `new Array` for chamada com um número como único argumento, então ela cria um *array* *sem itens*, mas com esse comprimento (*length*). -Let's see how one can shoot themself in the foot: +Vejamos como alguém pode se atraiçoar: ```js run -let arr = new Array(2); // will it create an array of [2] ? +let arr = new Array(2); // irá criar um array como [2] ? -alert( arr[0] ); // undefined! no elements. +alert( arr[0] ); // 'undefined!' elemento não definido. -alert( arr.length ); // length 2 +alert( arr.length ); // comprimento 2 ``` -In the code above, `new Array(number)` has all elements `undefined`. +No código acima, `new Array(number)` possui todos os elementos como `undefined`. -To evade such surprises, we usually use square brackets, unless we really know what we're doing. +Para evitar tais surpresas, nós geralmente utilizamos parênteses retos, a não ser que realmente saibamos o que estamos a fazer. -## Multidimensional arrays +## *Arrays* multidimensionais -Arrays can have items that are also arrays. We can use it for multidimensional arrays, to store matrices: +*Arrays* podem ter itens que também sejam arrays. Podemos os empregar em *arrays* multidimensionais, para armazenar matrizes: ```js run let matrix = [ @@ -394,24 +391,23 @@ let matrix = [ [7, 8, 9] ]; -alert( matrix[1][1] ); // the central element +alert( matrix[1][1] ); // o elemento central ``` -## toString - -Arrays have their own implementation of `toString` method that returns a comma-separated list of elements. +## *toString* -For instance: +Os *arrays* têm a sua própria implementação do método `toString`, que retorna uma lista de elementos separados por vírgulas. +Por exemplo: ```js run let arr = [1, 2, 3]; alert( arr ); // 1,2,3 -alert( String(arr) === '1,2,3' ); // true +alert( String(arr) === '1,2,3' ); // true (verdadeiro) ``` -Also, let's try this: +De igual modo, vamos tentar isto: ```js run alert( [] + 1 ); // "1" @@ -419,9 +415,9 @@ alert( [1] + 1 ); // "11" alert( [1,2] + 1 ); // "1,21" ``` -Arrays do not have `Symbol.toPrimitive`, neither a viable `valueOf`, they implement only `toString` conversion, so here `[]` becomes an empty string, `[1]` becomes `"1"` and `[1,2]` becomes `"1,2"`. +*Arrays* não têm `Symbol.toPrimitive`, nem um `valueOf` útil, eles apenas implementam a conversão `toString`, e assim `[]` se torna numa *string* vazia, `[1]` se torna em `"1"` e `[1,2]` em `"1,2"`. -When the binary plus `"+"` operator adds something to a string, it converts it to a string as well, so the next step looks like this: +Quando o operador mais `"+"` binário adiciona algo a uma *string*, ele também converte esse elemento para *string*, e assim os passos anteriores se parecem com: ```js run alert( "" + 1 ); // "1" @@ -429,36 +425,35 @@ alert( "1" + 1 ); // "11" alert( "1,2" + 1 ); // "1,21" ``` -## Summary +## Sumário -Array is a special kind of object, suited to storing and managing ordered data items. +O *array* é um tipo especial de objeto, apropriado para armazenar e gerir itens de dados ordenados. -- The declaration: +- A declaração: ```js - // square brackets (usual) + // parênteses retos (usual) let arr = [item1, item2...]; - // new Array (exceptionally rare) + // new Array (excepcionalmente rara) let arr = new Array(item1, item2...); ``` - The call to `new Array(number)` creates an array with the given length, but without elements. - -- The `length` property is the array length or, to be precise, its last numeric index plus one. It is auto-adjusted by array methods. -- If we shorten `length` manually, the array is truncated. + A chamada a `new Array(number)` cria um *array* com o dado comprimento, mas sem elementos. -We can use an array as a deque with the following operations: +- A propriedade `length` refere-se ao comprimento do *array* ou, para ser preciso, ao seu último indice numérico mais um. Ela é auto-ajustada por intermédio de métodos do *array*. +- Se nós encurtarmos `length` manualmente, o *array* é truncado. -- `push(...items)` adds `items` to the end. -- `pop()` removes the element from the end and returns it. -- `shift()` removes the element from the beginning and returns it. -- `unshift(...items)` adds items to the beginning. +Podemos usar um *array* como uma (estrutura de dados) *deque*, com as seguintes operações: -To loop over the elements of the array: - - `for (let i=0; i. +Para percorrer os elementos do *array*: + - `for (let i=0; i. From 080fb45d46174efae14296efbd9c46d0f1eeab88 Mon Sep 17 00:00:00 2001 From: Osvaldo Dias dos Santos Date: Sat, 5 Dec 2020 00:03:18 +0100 Subject: [PATCH 2/8] Update 'arrays' files translation. --- .../04-array/1-item-value/task.md | 4 +- .../04-array/10-maximal-subarray/solution.md | 8 +- .../04-array/10-maximal-subarray/task.md | 2 +- .../04-array/2-create-array/solution.md | 1 + .../04-array/2-create-array/task.md | 2 +- .../04-array/3-call-array-this/solution.md | 6 +- .../04-array/3-call-array-this/task.md | 3 +- .../04-array/5-array-input-sum/solution.md | 5 +- .../04-array/5-array-input-sum/task.md | 6 +- 1-js/05-data-types/04-array/article.md | 153 ++++++++++++------ 10 files changed, 124 insertions(+), 66 deletions(-) diff --git a/1-js/05-data-types/04-array/1-item-value/task.md b/1-js/05-data-types/04-array/1-item-value/task.md index 4b2cdce05..bec34fe5f 100644 --- a/1-js/05-data-types/04-array/1-item-value/task.md +++ b/1-js/05-data-types/04-array/1-item-value/task.md @@ -1,10 +1,10 @@ -importância: 3 +importance: 3 --- # Foi o *array* copiado? -O que irá mostrar este código? +O que irá este código mostrar? ```js let fruits = ["Maçã", "Pêra", "Laranja"]; diff --git a/1-js/05-data-types/04-array/10-maximal-subarray/solution.md b/1-js/05-data-types/04-array/10-maximal-subarray/solution.md index 61a9fc9e8..bc2e2b647 100644 --- a/1-js/05-data-types/04-array/10-maximal-subarray/solution.md +++ b/1-js/05-data-types/04-array/10-maximal-subarray/solution.md @@ -33,7 +33,7 @@ Por exemplo, para `[-1, 2, 3, -9, 11]`: 11 ``` -Na verdade, o código é um laço aninhado (*nested loop*): o externo percorre os elementos do *array*, e o interno calcula as subsomas que comecem pelo elemento atual. +Na verdade, o código é um laço aninhado (*nested loop*): o externo percorre os elementos do *array*, e o interno calcula as subsomas que começam pelo elemento atual. ```js run function getMaxSubSum(arr) { @@ -65,7 +65,7 @@ Para grandes *arrays* (1000, 10000 ou mais itens) tais algoritmos podem levar a Vamos percorrer o *array* e guardar a atual soma partial dos elementos na variável `s`. Se, a certa altura, `s` se tornar negativo, então faça a atribuição `s=0`. O máximo desses `s` será a resposta. -Se, a descrição for demasiado vaga, por favor veja o código; é realmente curto: +Se a descrição for demasiado vaga, por favor veja o código, é realmente curto: ```js run demo function getMaxSubSum(arr) { @@ -89,6 +89,6 @@ alert( getMaxSubSum([1, 2, 3]) ); // 6 alert( getMaxSubSum([-1, -2, -3]) ); // 0 ``` -O algoritmo requere exatamente 1 passagem sobre o *array*, portanto o tempo de complexidade é O(n). +O algoritmo requere exatamente 1 passagem pelo *array*, portanto o tempo de complexidade é O(n). -Pode encontrar informação mais detalhada sobre o algoritmo aqui: [Sublista contígua de soma máxima](https://pt.wikipedia.org/wiki/Sublista_cont%C3%ADgua_de_soma_m%C3%A1xima). Se, ainda não for óbvio como isso funciona, então por favor percorra cada algoritmo nos exemplos acima e veja como trabalha, é melhor do que quaisquer palavras. +Pode encontrar informação mais detalhada sobre o algoritmo aqui: [Sublista contígua de soma máxima](https://pt.wikipedia.org/wiki/Sublista_cont%C3%ADgua_de_soma_m%C3%A1xima). Se, ainda não for óbvio porque isso funciona, então por favor rasteie cada algoritmo nos exemplos acima e veja como trabalha, é melhor do que quaisquer palavras. diff --git a/1-js/05-data-types/04-array/10-maximal-subarray/task.md b/1-js/05-data-types/04-array/10-maximal-subarray/task.md index ed3badf3f..fbb5b5f41 100644 --- a/1-js/05-data-types/04-array/10-maximal-subarray/task.md +++ b/1-js/05-data-types/04-array/10-maximal-subarray/task.md @@ -1,4 +1,4 @@ -importância: 2 +importance: 2 --- diff --git a/1-js/05-data-types/04-array/2-create-array/solution.md b/1-js/05-data-types/04-array/2-create-array/solution.md index b9e7c5a2e..cde5b72b1 100644 --- a/1-js/05-data-types/04-array/2-create-array/solution.md +++ b/1-js/05-data-types/04-array/2-create-array/solution.md @@ -7,3 +7,4 @@ styles[Math.floor((styles.length - 1) / 2)] = "Clássicos"; alert( styles.shift() ); styles.unshift("Rap", "Reggae"); ``` + diff --git a/1-js/05-data-types/04-array/2-create-array/task.md b/1-js/05-data-types/04-array/2-create-array/task.md index 9f37f0cbe..9be6742f8 100644 --- a/1-js/05-data-types/04-array/2-create-array/task.md +++ b/1-js/05-data-types/04-array/2-create-array/task.md @@ -1,4 +1,4 @@ -importância: 5 +importance: 5 --- diff --git a/1-js/05-data-types/04-array/3-call-array-this/solution.md b/1-js/05-data-types/04-array/3-call-array-this/solution.md index ce5450b56..0dcd42c73 100644 --- a/1-js/05-data-types/04-array/3-call-array-this/solution.md +++ b/1-js/05-data-types/04-array/3-call-array-this/solution.md @@ -1,6 +1,6 @@ A invocação `arr[2]()` é sintáticamente a antiga `obj[method]()`; no papel de `obj` temos `arr`, e no papel de `method` temos `2`. -Assim, temos uma chamada da função `arr[2]` como um método de objeto. Naturalmente, como ela recebe em `this` a referência ao objeto `arr`, ela mostra como saída o *array*: +Assim, temos uma chamada da função `arr[2]` como um método de objeto. Naturalmente, como ela recebe em `this` a referência ao objeto `arr`, ela exibe o *array*: ```js run let arr = ["a", "b"]; @@ -9,7 +9,7 @@ arr.push(function() { alert( this ); }) -arr[2](); // "a","b", function +arr[2](); // "a","b", function(){...} ``` -O *array* tem 3 valores: os dois inicias, mais a função. +O *array* tem 3 valores: inicialmente dois, mais a função. diff --git a/1-js/05-data-types/04-array/3-call-array-this/task.md b/1-js/05-data-types/04-array/3-call-array-this/task.md index 43f143716..f20645101 100644 --- a/1-js/05-data-types/04-array/3-call-array-this/task.md +++ b/1-js/05-data-types/04-array/3-call-array-this/task.md @@ -1,4 +1,4 @@ -importância: 5 +importance: 5 --- @@ -15,3 +15,4 @@ arr.push(function() { arr[2](); // ? ``` + diff --git a/1-js/05-data-types/04-array/5-array-input-sum/solution.md b/1-js/05-data-types/04-array/5-array-input-sum/solution.md index 4695d34fd..5264a9ed6 100644 --- a/1-js/05-data-types/04-array/5-array-input-sum/solution.md +++ b/1-js/05-data-types/04-array/5-array-input-sum/solution.md @@ -1,4 +1,4 @@ -Por favor repare no subtítulo, e em importantes detalhes da solução. Nós não convertemos `value` para número imediatamente após `prompt`, porque depois de `value = +value` não temos como diferenciar uma *string* vazia (sinal para parar) de zero (número válido). Em vez disso, o fazemos mais tarde. +Por favor repare no subtítulo, e em detalhes importantes da solução. Nós não convertemos `value` para número imediatamente após `prompt`, porque depois de `value = +value` não teríamos como ver a diferença entre uma *string* vazia (o sinal para parar) e zero (um número válido). Assim, nós o fazemos mais tarde. ```js run demo @@ -10,7 +10,7 @@ function sumInput() { let value = prompt("Um número, por favor?", 0); - // devemos cancelar? + // nós devemos cancelar? if (value === "" || value === null || !isFinite(value)) break; numbers.push(+value); @@ -25,3 +25,4 @@ function sumInput() { alert( sumInput() ); ``` + diff --git a/1-js/05-data-types/04-array/5-array-input-sum/task.md b/1-js/05-data-types/04-array/5-array-input-sum/task.md index c3d6035a1..28909e4dc 100644 --- a/1-js/05-data-types/04-array/5-array-input-sum/task.md +++ b/1-js/05-data-types/04-array/5-array-input-sum/task.md @@ -1,4 +1,4 @@ -importância: 4 +importance: 4 --- @@ -7,9 +7,9 @@ importância: 4 Escreva a função `sumInput()` que: - Peça ao utilizador por valores usando `prompt` e guarde os valores num *array*. -- Acabe o pedido quando o utilizador inserir um valor não-numérico, uma *string* vazia, ou pressione "*Cancel*". +- Não peça mais quando o utilizador inserir um valor não-numérico, uma *string* vazia, ou pressione "*Cancel*". - Calcule e retorne a soma dos itens no *array*. -P.S. Um zero `0` é um número válido, por favor não pare a inserção com zero. +P.S. Um zero `0` é um número válido, por favor não pare de pedir com zero. [demo] diff --git a/1-js/05-data-types/04-array/article.md b/1-js/05-data-types/04-array/article.md index da39c8cf0..4252852d6 100644 --- a/1-js/05-data-types/04-array/article.md +++ b/1-js/05-data-types/04-array/article.md @@ -2,7 +2,7 @@ Objetos permitem-lhe armazenar coleções de valores por chaves. É bom. -Mas, frequentemente precisamos de uma *coleção ordenada*, onde tenhamos um 1º, 2º, 3º elemento e assim por diante. Por exemplo, precisamos dela para armazenar uma lista de algo como: visitantes, bens, elementos de HTML, etc. +Mas, frequentemente precisamos de uma *coleção ordenada*, onde tenhamos um 1º, 2º, 3º elemento e assim por diante. Por exemplo, precisamos dela para armazenar uma lista de algo como: visitantes, bens, elementos de HTML, etc. Não é conveniente usar um objeto aqui, porque ele não dispõe de métodos para gerir a ordem dos elementos. Não podemos inserir uma nova propriedade “entre” outras já existentes. Objetos simplesmente não são adequados a tal uso. @@ -23,9 +23,9 @@ Quase sempre é usada a segunda sintaxe. Podemos fornecer elementos iniciais ent let fruits = ["Maçã", "Laranja", "Ameixa"]; ``` -Os elementos de um *array* são numerados, começando por zero. +Os elementos de um *array* são numerados, começando por zero. -Podemos obter um elemento por meio do seu número entre parênteses retos: +Podemos obter um elemento pelo seu número entre parênteses retos: ```js run let fruits = ["Maçã", "Laranja", "Ameixa"]; @@ -47,7 +47,7 @@ fruits[2] = 'Pêra'; // now ["Maçã", "Laranja", "Pêra"] fruits[3] = 'Limão'; // now ["Maçã", "Laranja", "Pêra", "Limão"] ``` -A contagem total dos elementos no *array* é o seu `*length*` (comprimento): +O número total dos elementos no *array* é o seu `*length*` (comprimento): ```js run let fruits = ["Maçã", "Laranja", "Ameixa"]; @@ -55,7 +55,7 @@ let fruits = ["Maçã", "Laranja", "Ameixa"]; alert( fruits.length ); // 3 ``` -Podemos também utilizar `alert` para mostrar todo o *array*. +Podemos também usar `alert` para exibir todo o *array*. ```js run let fruits = ["Maçã", "Laranja", "Ameixa"]; @@ -92,18 +92,19 @@ let fruits = [ O estilo de "vírgula final" torna mais fácil inserir/remover itens, porque todas as linhas se tornam semelhantes. ```` + ## Métodos pop/push, shift/unshift -Uma [fila](https://pt.wikipedia.org/wiki/FIFO) (*queue*) é um dos usos mais comuns de um *array*. Em ciência dos computadores, isto significa uma coleção ordenada de elementos que suporta duas operações: +Uma [fila](https://pt.wikipedia.org/wiki/FIFO) (*queue*) é um dos usos mais comuns de um *array*. Em ciência dos computadores, isto significa uma coleção ordenada de elementos que suporta duas operações: - `push` adiciona um elemento ao final. -- `shift` obtem um elemento do início, avançando a fila, de modo que o 2º elemento se torne no 1º. +- `shift` obtém um elemento do início, avançando a fila, de modo que o 2º elemento se torne no 1º. ![](queue.svg) Os *arrays* suportam ambas as operações. -Na prática, nós as precisamos frequentemente. Por exemplo, uma fila de mensagens que precise de ser mostrada no ecrâ. +Na prática, nós as precisamos com muita frequência. Por exemplo, uma fila de mensagens que precisa de ser mostrada no ecrã. Existe um outro caso prático para *arrays* -- a estrutura de dados chamada [pilha](https://pt.wikipedia.org/wiki/Pilha_(inform%C3%A1tica)) (stack). @@ -118,10 +119,11 @@ Uma pilha (*stack*) é geralmente ilustrada como um baralho de cartas: novas car ![](stack.svg) -Para pilhas (*stacks*), o último item inserido é recebido primeiro, o que também é chamado de princípio *LIFO* (*Last-In-First-Out*) [o-Último-a-Entrar-é-o-Primeiro-a-Sair]. Para filas (*queues*), nós temos *FIFO* (*First-In-First-Out*) [o-Primeiro-a-Entrar-é-o-Primeiro-a-Sair]. -Os *arrays* em JavaScript podem funcionar tanto como uma fila, como uma pilha. Eles permitem-lhe adicionar/remover elementos quer ao/do início como ao/do final. +Para pilhas, o último item inserido é recebido primeiro, o que também é chamado de princípio *LIFO* (*Last-In-First-Out*) (o-Último-a-Entrar-é-o-Primeiro-a-Sair). Para filas (*queues*), nós temos *FIFO* (*First-In-First-Out*) (o-Primeiro-a-Entrar-é-o-Primeiro-a-Sair). + +Os *arrays* em JavaScript podem tanto trabalhar como uma fila, quer como uma pilha. Eles permitem-lhe adicionar/remover elementos quer ao/do início como ao/do final. -Em ciência dos computadores, a estrutura de dados que o permite é chamada [deque](https://pt.wikipedia.org/wiki/Deque_(estruturas_de_dados)). +Em ciência dos computadores, a estrutura de dados que permite isto é chamada de [deque](https://pt.wikipedia.org/wiki/Deque_(estruturas_de_dados)). **Métodos que trabalham no final do _array_:** @@ -187,11 +189,11 @@ alert( fruits ); ## Internamente -Um *array* é um tipo especial de objeto. Os parêntesis retos utilizados para aceder a uma propriedade `arr[0]` vêm, na verdade, da sintaxe de objetos. Números são usados como chaves. +Um *array* é um tipo especial de objeto. Os parêntesis retos usados para aceder a uma propriedade `arr[0]` vêm, na verdade, da sintaxe de objetos. Isto, é essencialmente o mesmo que `obj[key]`, onde `arr` é o objeto, e números são usados como chaves. Eles são uma extensão aos objetos, fornecendo métodos especiais para trabalhar com coleções ordenadas de dados e também a propriedade `length`. Assim, no seu núcleo um *array* é um objeto. -Lembre-se, existem apenas 7 tipos básicos em JavaScript. O *array* é um objeto e portanto comporta-se como um objeto. +Lembre-se, só existem oito tipos de dados básicos em JavaScript (veja o capítulo [Tipos de dads](info:types) para mais informação). O *array* é um objeto e portanto comporta-se como um objeto. Por exemplo, ele é copiado por referência: @@ -202,12 +204,12 @@ let arr = fruits; // cópia por referência (duas variáveis referenciam o mesmo alert( arr === fruits ); // true (verdadeiro) -arr.push("Pear"); // modifique o array por referência +arr.push("Pêra"); // modifique o array por referência alert( fruits ); // Banana, Pêra - 2 itens agora ``` -...Mas, o que torna *arrays* realmente especiais é a sua representação interna. O interpretador de JavaScript tenta armazenar os seus elementos numa área contígua de memória, um após outro, precisamente como mostrado nas ilustrações deste capítulo, e existem também outras optimizações para fazerem os *arrays* trabalhar verdadeiramente rápido. +...Mas, o que torna os *arrays* realmente especiais é a sua representação interna. O interpretador de JavaScript tenta armazenar os seus elementos numa área contígua de memória, um após outro, precisamente como mostrado nas ilustrações deste capítulo, e existem também outras optimizações para fazerem os *arrays* trabalhar verdadeiramente rápido. Mas, todas elas quebram se pararmos de trabalhar com um *array* como uma "coleção ordenada", e começarmos a trabalhar com ele como se fosse um objeto regular. @@ -223,7 +225,7 @@ fruits.age = 25; // cria uma propriedade com um nome arbitrário Isso é possível, porque *arrays* são objetos na sua base. Podemos adicionar qualquer propriedade a eles. -Mas, o interpretador de JavaScript (*JavaSript engine*) verá que nós estamos a trabalhar com o *array* como com um objeto regular. Optimizações especificas para *arrays* não são adequadas a estes casos e serão desativadas, os seus benifícios desaparecem. +Mas, o interpretador irá ver que nós estamos a trabalhar com o *array* como com um objeto regular. Optimizações especificas para *arrays* não são adequadas a estes casos e serão desativadas, os seus benefícios desaparecem. Formas de má utilização de um *array*: @@ -235,22 +237,22 @@ Por favor, pense em *arrays* como estruturas especiais para trabalhar com *dados ## Performance -Métodos `push/pop` são executados rápidamente, enquanto `shift/unshift` são lentos. +Os métodos `push/pop` correm rápidamente, enquanto `shift/unshift` são lentos. ![](array-speed.svg) -Porque é mais rápido trabalhar no final de um *array*, do que no seu início? Vejamos o que acontece durante a execução: +Porque é mais rápido trabalhar no final de um *array*, do que no seu início? Vejamos o que acontece durante a execução: ```js fruits.shift(); // tome 1 elemento do início ``` -Não é suficiente tomar e remover o elemento com o número `0`. Os outros elementos também necessitam de ser renumerados. +Não é suficiente tomar e remover o elemento com o número `0`. Os outros elementos também precisam de ser renumerados. A operação `shift` deve efetuar 3 coisas: -1. Remover o elemento com o indice `0`. -2. Mover todos os elementos para a esquerda, renumerando-os do indice `1` para `0`, do `2` para `1`, e assim por diante. +1. Remover o elemento com o índice `0`. +2. Mover todos os elementos para a esquerda, renumerando-os do índice `1` para `0`, do `2` para `1`, e assim por diante. 3. Atualizar a propriedade `length`. ![](array-shift.svg) @@ -259,7 +261,7 @@ A operação `shift` deve efetuar 3 coisas: À semelhança acontece com `unshift`: para adicionar um elemento ao início do *array*, nós primeiro precisamos de mover os elementos existentes para à direita, e aumentar os seus indices. -E, o que se passa com `push/pop`? Eles, não precisam de mover nada. Para extrair um elemento do final, o método `pop` elimina o indice e diminui `length`. +E, o que se passa com `push/pop`? Eles, não precisam de mover nada. Para extrair um elemento do final, o método `pop` elimina o índice e diminui `length`. As ações para a operação `pop`: @@ -269,13 +271,13 @@ fruits.pop(); // tome 1 elemento do final ![](array-pop.svg) -**O método `pop` não precisa de mover nada, porque os outros elementos mantêm os seus indices. É por isso que são extremamente rápidos.** +**O método `pop` não precisa de mover nada, porque os outros elementos mantêm os seus indices. É por isso que é extremamente rápido.** O semelhante se passa com o método `push`. ## *Loops* -Uma das velhas formas para percorrer itens de um *array*, é através de um ciclo (*loop*) `for` sobre os seus indices: +Uma das velhas formas para percorrer itens de um *array*, é o ciclo (*loop*) `for` sobre os seus indices: ```js run let arr = ["Maçã", "Laranja", "Pêra"]; @@ -287,18 +289,18 @@ for (let i = 0; i < arr.length; i++) { } ``` -Mas, para *arrays* existe um outro ciclo (*loop*), `for..of`: +Mas, para *arrays* existe um outro ciclo, o `for..of`: ```js run let fruits = ["Maçã", "Laranja", "Ameixa"]; // itera sobre os elementos do array for (let fruit of fruits) { - alert( fruit ); + alert( fruit ); } ``` -O `for..of` não dá acesso ao número do elemento atual, mas apenas ao seu valor, contudo em muitos casos é o suficiente. E a sintaxe é mais curta. +O `for..of` não dá acesso ao índice do elemento atual, mas apenas ao seu valor, contudo em muitos casos é o suficiente. E a sintaxe é mais curta. Tecnicamente, uma vez que *arrays* são objetos, também é possível usar `for..in`: @@ -312,21 +314,22 @@ for (let key in arr) { } ``` -Mas, na verdade é uma má ideia. Existem problemas potenciais com isso: +Mas, na verdade é uma má ideia. Existem potenciais problemas com isso: -1. O laço (*loop*) `for..in` itera sobre *todas as propriedades*, não apenas sobre as numéricas. +1. O ciclo `for..in` itera sobre *todas as propriedades*, não apenas sobre as numéricas. - Existem os objetos chamados de "semelhantes-a-arrays" (*array-like*), no navegador (*browser*) e em outros ambientes, que *se parecem com _arrays_*. Isto é, eles têm as propriedades `length` (comprimento) e indices, mas também podem ter outras propriedades e métodos não-numéricos, que geralmente não precisamos. Contudo, o laço (*loop*) `for..in` listará todos eles. Assim, se nós precisarmos de trabalhar com objetos semelhantes-a-arrays, aí estas propriedades "extra" podem constituir um problema. + Existem os objetos chamados de "semelhantes-a-arrays" (*array-like*), no navegador e em outros ambientes, que *se parecem com _arrays_*. Isto é, eles têm as propriedades `length` e indices, mas também podem ter outras propriedades não-numéricas e métodos, que geralmente não precisamos. Contudo, o ciclo `for..in` irá listar todos elas. Assim, se precisarmos de trabalhar com objetos semelhantes-a-arrays, aí essas propriedades "extra" podem constituir um problema. -2. O laço (*loop*) `for..in` está optimizado para objetos genéricos, não *arrays*, e desta forma é 10-100 mais lento. Contudo, ainda é muito rápido. A velocidade pode apenas ser importante em pontos cruciais (*bottlenecks*), e em caso contrário parecer irrelevante. Mas, ainda assim deveríamos estar de sobreaviso sobre a diferença. +2. O laço (*loop*) `for..in` está optimizado para objetos genéricos, não *arrays*, e desta forma é 10-100 vezes mais lento. Claro que ainda é muito rápido. A velocidade pode apenas ser importante em pontos cruciais (*bottlenecks*). Mas, deveríamos estar conscientes desta diferença. Em geral, não deveríamos usar `for..in` para *arrays*. + ## Uma palavra sobre "comprimento" -A propriedade `length` (comprimento) se atualiza automaticamente quando nós modificamos o *array*. Para ser preciso, na verdade ela não é a contagem dos valores no *array*, mas sim o maior indice numérico mais um. +A propriedade `length` (comprimento) é automaticamente atualizada quando nós modificamos o *array*. Para ser preciso, na verdade ela não é a contagem dos valores no *array*, mas sim o maior índice numérico mais um. -Por exemplo, um único elemento com um indice alto produz um comprimento grande: +Por exemplo, um único elemento com um índice alto conduz a um comprimento grande: ```js run let fruits = []; @@ -351,10 +354,10 @@ arr.length = 5; // retorna o comprimento de volta alert( arr[3] ); // undefined: os valores não reaparecem ``` -Assim, a forma mais simples de limpar um array é: `arr.length = 0;`. +Assim, a forma mais simples para limpar um array é: `arr.length = 0;`. -## new Array() [#novo-array] +## new Array() [#new-array] Há mais uma sintaxe para se criar um *array*: @@ -364,25 +367,25 @@ let arr = *!*new Array*/!*("Maçã", "Pêra", "etc"); Raramente é usada, porque os parênteses retos são mais curtos `[]`. Além disso, existe uma característica peculiar a acompanhá-la. -Se `new Array` for chamada com um número como único argumento, então ela cria um *array* *sem itens*, mas com esse comprimento (*length*). +Se `new Array` for chamada com um único argumento e sendo este numérico, então ela cria um *array* *sem itens, mas com esse comprimento*. -Vejamos como alguém pode se atraiçoar: +Vejamos como alguém pode se atraiçoar a si próprio: ```js run let arr = new Array(2); // irá criar um array como [2] ? -alert( arr[0] ); // 'undefined!' elemento não definido. +alert( arr[0] ); // 'undefined!' nenhum elemento. alert( arr.length ); // comprimento 2 ``` -No código acima, `new Array(number)` possui todos os elementos como `undefined`. +No código acima, `new Array(number)` tem todos os elementos como `undefined`. Para evitar tais surpresas, nós geralmente utilizamos parênteses retos, a não ser que realmente saibamos o que estamos a fazer. ## *Arrays* multidimensionais -*Arrays* podem ter itens que também sejam arrays. Podemos os empregar em *arrays* multidimensionais, para armazenar matrizes: +*Arrays* podem ter itens que também sejam arrays. Podemos os usar em *arrays* multidimensionais, por exemplo para armazenar matrizes: ```js run let matrix = [ @@ -400,6 +403,7 @@ Os *arrays* têm a sua própria implementação do método `toString`, que retor Por exemplo: + ```js run let arr = [1, 2, 3]; @@ -415,7 +419,7 @@ alert( [1] + 1 ); // "11" alert( [1,2] + 1 ); // "1,21" ``` -*Arrays* não têm `Symbol.toPrimitive`, nem um `valueOf` útil, eles apenas implementam a conversão `toString`, e assim `[]` se torna numa *string* vazia, `[1]` se torna em `"1"` e `[1,2]` em `"1,2"`. +*Arrays* não têm `Symbol.toPrimitive`, nem um `valueOf` útil, eles apenas implementam a conversão `toString`, e assim `[]` se transforma numa *string* vazia, `[1]` se transforma em `"1"` e `[1,2]` em `"1,2"`. Quando o operador mais `"+"` binário adiciona algo a uma *string*, ele também converte esse elemento para *string*, e assim os passos anteriores se parecem com: @@ -425,6 +429,53 @@ alert( "1" + 1 ); // "11" alert( "1,2" + 1 ); // "1,21" ``` +## Não compare arrays com == + +Os *arrays* em JavaScript, ao contrário de algumas outras linguagens de programação, não devem ser comparados com o operador `==`. + +Este operador não dispõe de um tratamento especial para *arrays*, ele trabalha com eles como com quaisquer objetos. + +Vamos nos recordar das regras: + +- Dois objetos são iguais `==` apenas se eles referenciam o mesmo objeto. +- Se um dos argumentos de `==` for um objeto, e o outro um primitivo, então o objeto é convertido para primitivo, como explicado no capítulo . +- ...Com a exceção de `null` e `undefined` que se igualam `==` entre si e a nada mais. + +A comparação exata (*strict*) `===` é ainda mais simples, porque ela não converte tipos. + +Assim, se nós compararmos *arrays* com `==`, eles nunca são iguais, a não ser que estejamos a comparar duas variáveis que referenciam exatamente o mesmo *array*. + +Por exemplo: +```js run +alert( [] == [] ); // false +alert( [0] == [0] ); // false +``` + +Estes *arrays* tecnicamente são objetos diferentes. Então, eles não são iguais. O operador `==` não faz uma comparação item-por-item. + +A comparação com primitivos também pode dar resultados aparentemente estranhos: + +```js run +alert( 0 == [] ); // true + +alert('0' == [] ); // false +``` + +Aqui, em ambos os casos, nós comparamos um primitivo a um objeto *array*. Portanto, o *array* `[]` é convertido para primitivo para os propósitos da comparação e se transforma numa *string* vazia `''`. + +Então, a comparação continua entre primitivos, como é descrito no capítulo : + +```js run +// depois de [] ser convertido para '' +alert( 0 == '' ); // true, como '' é convertida para 0 + +alert('0' == '' ); // false, nenhuma conversão de tipos de dados, só strings diferentes +``` + +Então, como comparar *arrays*? + +Isto é simples: não use o operador `==`. Em vez disto, os compare item-por-item num laço (*loop*) ou usando métodos de iteração explicados no próximo capítulo. + ## Sumário O *array* é um tipo especial de objeto, apropriado para armazenar e gerir itens de dados ordenados. @@ -439,21 +490,25 @@ O *array* é um tipo especial de objeto, apropriado para armazenar e gerir itens let arr = new Array(item1, item2...); ``` - A chamada a `new Array(number)` cria um *array* com o dado comprimento, mas sem elementos. + A chamada a `new Array(number)` cria um *array* com o comprimento dado, mas sem elementos. -- A propriedade `length` refere-se ao comprimento do *array* ou, para ser preciso, ao seu último indice numérico mais um. Ela é auto-ajustada por intermédio de métodos do *array*. +- A propriedade `length` é o comprimento do *array* ou, para ser preciso, o seu último índice numérico mais um. Ela é auto-ajustada por métodos do *array*. - Se nós encurtarmos `length` manualmente, o *array* é truncado. -Podemos usar um *array* como uma (estrutura de dados) *deque*, com as seguintes operações: +Podemos usar um *array* como uma *deque* (estrutura de dados), com as seguintes operações: - `push(...items)` adiciona `items` ao final. -- `pop()` remove o elemento no final, e o retorna. -- `shift()` remove o elemento no início, e o retorna. -- `unshift(...items)` adiciona itens ao início. +- `pop()` remove o elemento do final, e o retorna. +- `shift()` remove o elemento do início, e o retorna. +- `unshift(...items)` adiciona `items` ao início. Para percorrer os elementos do *array*: - - `for (let i=0; i. +Para comparar *arrays*, não use o operador `==` (como também `>`, `<` ou outros), porque eles não dispõem de tratamento especial para *arrays*. Eles os tratam como quaisquer objetos, mas não é o que geralmente queremos. + +No seu lugar, você pode usar o laço `for..of` para comparar *arrays* item-por-item. + +Nós voltaremos aos *arrays*, e estudaremos mais métodos para adicionar, remover, extrair elementos e os ordenar no capítulo . From 87b8ad3326e67ad480c73f035614eefaba273f5f Mon Sep 17 00:00:00 2001 From: Osvaldo Dias dos Santos Date: Fri, 21 May 2021 19:39:57 +0100 Subject: [PATCH 3/8] Update translation. --- .../04-array/10-maximal-subarray/solution.md | 8 ++--- .../04-array/10-maximal-subarray/task.md | 16 ++++----- 1-js/05-data-types/04-array/article.md | 34 +++++++++---------- 3 files changed, 28 insertions(+), 30 deletions(-) diff --git a/1-js/05-data-types/04-array/10-maximal-subarray/solution.md b/1-js/05-data-types/04-array/10-maximal-subarray/solution.md index bc2e2b647..28a6ac669 100644 --- a/1-js/05-data-types/04-array/10-maximal-subarray/solution.md +++ b/1-js/05-data-types/04-array/10-maximal-subarray/solution.md @@ -33,7 +33,7 @@ Por exemplo, para `[-1, 2, 3, -9, 11]`: 11 ``` -Na verdade, o código é um laço aninhado (*nested loop*): o externo percorre os elementos do *array*, e o interno calcula as subsomas que começam pelo elemento atual. +Na verdade, o código é um laço aninhado (*nested loop*): o externo percorre os elementos do *array*, e o interno calcula as subsomas que começam pelo elemento corrente. ```js run function getMaxSubSum(arr) { @@ -57,13 +57,13 @@ alert( getMaxSubSum([1, 2, 3]) ); // 6 alert( getMaxSubSum([100, -9, 2, -3, 5]) ); // 100 ``` -A solução tem um tempo de complexidade de [O(n2)](https://en.wikipedia.org/wiki/Big_O_notation). Por outras palavras, se aumentarmos o tamanho do *array* para o dobro, o algoritmo demorará 4 vezes mais. +A solução tem um tempo de complexidade de [O(n2)](https://pt.wikipedia.org/wiki/Grande-O). Por outras palavras, se aumentarmos o tamanho do *array* para o dobro, o algoritmo demorará 4 vezes mais. Para grandes *arrays* (1000, 10000 ou mais itens) tais algoritmos podem levar a sérias lentidões. # Solução rápida -Vamos percorrer o *array* e guardar a atual soma partial dos elementos na variável `s`. Se, a certa altura, `s` se tornar negativo, então faça a atribuição `s=0`. O máximo desses `s` será a resposta. +Vamos percorrer o *array* e guardar a corrente soma partial dos elementos na variável `s`. Se, a certa altura, `s` se tornar negativo, então faça a atribuição `s=0`. O máximo de todos os `s` será a resposta. Se a descrição for demasiado vaga, por favor veja o código, é realmente curto: @@ -73,7 +73,7 @@ function getMaxSubSum(arr) { let partialSum = 0; for (let item of arr) { // por cada item de arr - partialSum += item; // o adicione a partialSum ('s' na descrição) + partialSum += item; // adicione-o a partialSum ('s' na descrição) maxSum = Math.max(maxSum, partialSum); // guarde o máximo if (partialSum < 0) partialSum = 0; // zero se negativo } diff --git a/1-js/05-data-types/04-array/10-maximal-subarray/task.md b/1-js/05-data-types/04-array/10-maximal-subarray/task.md index fbb5b5f41..e2b9b12c7 100644 --- a/1-js/05-data-types/04-array/10-maximal-subarray/task.md +++ b/1-js/05-data-types/04-array/10-maximal-subarray/task.md @@ -2,7 +2,7 @@ importance: 2 --- -# Um máximo *subarray* +# Um *subarray* máximo A entrada é um *array* de números, ex. `arr = [1, -2, 3, 4, -9, 6]`. @@ -13,12 +13,12 @@ Escreva a função `getMaxSubSum(arr)` que irá retornar essa soma. Por exemplo: ```js -getMaxSubSum([-1, *!*2, 3*/!*, -9]) = 5 (a soma dos itens em destaque) -getMaxSubSum([*!*2, -1, 2, 3*/!*, -9]) = 6 -getMaxSubSum([-1, 2, 3, -9, *!*11*/!*]) = 11 -getMaxSubSum([-2, -1, *!*1, 2*/!*]) = 3 -getMaxSubSum([*!*100*/!*, -9, 2, -3, 5]) = 100 -getMaxSubSum([*!*1, 2, 3*/!*]) = 6 (tome todos) +getMaxSubSum([-1, *!*2, 3*/!*, -9]) == 5 (a soma dos itens em destaque) +getMaxSubSum([*!*2, -1, 2, 3*/!*, -9]) == 6 +getMaxSubSum([-1, 2, 3, -9, *!*11*/!*]) == 11 +getMaxSubSum([-2, -1, *!*1, 2*/!*]) == 3 +getMaxSubSum([*!*100*/!*, -9, 2, -3, 5]) == 100 +getMaxSubSum([*!*1, 2, 3*/!*]) == 6 (tome todos) ``` Se todos os itens forem negativos, significa que não tomamos nenhum (o *subarray* está vazio), então a soma é zero: @@ -27,4 +27,4 @@ Se todos os itens forem negativos, significa que não tomamos nenhum (o *subarra getMaxSubSum([-1, -2, -3]) = 0 ``` -Por favor, tente pensar numa solução rápida: [O(n2)](https://en.wikipedia.org/wiki/Big_O_notation), ou mesmo O(n) se puder. +Por favor, tente pensar numa solução rápida: [O(n2)](https://pt.wikipedia.org/wiki/Grande-O), ou mesmo O(n) se puder. diff --git a/1-js/05-data-types/04-array/article.md b/1-js/05-data-types/04-array/article.md index 4252852d6..0a6e52d91 100644 --- a/1-js/05-data-types/04-array/article.md +++ b/1-js/05-data-types/04-array/article.md @@ -17,7 +17,7 @@ let arr = new Array(); let arr = []; ``` -Quase sempre é usada a segunda sintaxe. Podemos fornecer elementos iniciais entre os parênteses: +Quase sempre é usada a segunda sintaxe. Também podemos fornecer elementos iniciais entre os parênteses: ```js let fruits = ["Maçã", "Laranja", "Ameixa"]; @@ -95,7 +95,7 @@ O estilo de "vírgula final" torna mais fácil inserir/remover itens, porque tod ## Métodos pop/push, shift/unshift -Uma [fila](https://pt.wikipedia.org/wiki/FIFO) (*queue*) é um dos usos mais comuns de um *array*. Em ciência dos computadores, isto significa uma coleção ordenada de elementos que suporta duas operações: +Uma [queue](https://en.wikipedia.org/wiki/Queue_(abstract_data_type)) (*fila*) é um dos usos mais comuns de um *array*. Em ciência dos computadores, isto significa uma coleção ordenada de elementos que suporta duas operações: - `push` adiciona um elemento ao final. - `shift` obtém um elemento do início, avançando a fila, de modo que o 2º elemento se torne no 1º. @@ -104,16 +104,16 @@ Uma [fila](https://pt.wikipedia.org/wiki/FIFO) (*queue*) é um dos usos mais com Os *arrays* suportam ambas as operações. -Na prática, nós as precisamos com muita frequência. Por exemplo, uma fila de mensagens que precisa de ser mostrada no ecrã. +Na prática, nós a precisamos com muita frequência. Por exemplo, uma fila de mensagens que precisa de ser mostrada no ecrã. -Existe um outro caso prático para *arrays* -- a estrutura de dados chamada [pilha](https://pt.wikipedia.org/wiki/Pilha_(inform%C3%A1tica)) (stack). +Existe um outro caso prático para *arrays* -- a estrutura de dados chamada [pilha](https://pt.wikipedia.org/wiki/Pilha_(inform%C3%A1tica)) (*stack*). Ela suporta duas operações: - `push` adiciona um elemento ao final. - `pop` toma um elemento do final. -Assim, novos elementos são adicionados ou tomados sempre a partir do "final". +Assim, novos elementos são adicionados ou tomados sempre ao/do "final". Uma pilha (*stack*) é geralmente ilustrada como um baralho de cartas: novas cartas são adicionadas ao topo ou tiradas do topo: @@ -121,7 +121,7 @@ Uma pilha (*stack*) é geralmente ilustrada como um baralho de cartas: novas car Para pilhas, o último item inserido é recebido primeiro, o que também é chamado de princípio *LIFO* (*Last-In-First-Out*) (o-Último-a-Entrar-é-o-Primeiro-a-Sair). Para filas (*queues*), nós temos *FIFO* (*First-In-First-Out*) (o-Primeiro-a-Entrar-é-o-Primeiro-a-Sair). -Os *arrays* em JavaScript podem tanto trabalhar como uma fila, quer como uma pilha. Eles permitem-lhe adicionar/remover elementos quer ao/do início como ao/do final. +Os *arrays* em JavaScript tanto podem trabalhar como uma fila, como também uma pilha. Eles permitem-lhe adicionar/remover elementos quer ao/do início como ao/do final. Em ciência dos computadores, a estrutura de dados que permite isto é chamada de [deque](https://pt.wikipedia.org/wiki/Deque_(estruturas_de_dados)). @@ -149,7 +149,7 @@ Em ciência dos computadores, a estrutura de dados que permite isto é chamada d alert( fruits ); // Maçã, Laranja, Pêra ``` - A invocação `fruits.push(...)` é igual a `fruits[fruits.length] = ...`. + A chamada `fruits.push(...)` é igual a `fruits[fruits.length] = ...`. **Métodos que trabalham no início do _array_:** @@ -225,7 +225,7 @@ fruits.age = 25; // cria uma propriedade com um nome arbitrário Isso é possível, porque *arrays* são objetos na sua base. Podemos adicionar qualquer propriedade a eles. -Mas, o interpretador irá ver que nós estamos a trabalhar com o *array* como com um objeto regular. Optimizações especificas para *arrays* não são adequadas a estes casos e serão desativadas, os seus benefícios desaparecem. +Mas, o interpretador irá ver que nós estamos a trabalhar com o *array* como com um objeto regular. Optimizações especificas para *arrays* não são adequadas a tais casos e serão desativadas, os seus benefícios desaparecem. Formas de má utilização de um *array*: @@ -259,9 +259,9 @@ A operação `shift` deve efetuar 3 coisas: **Quantos mais elementos no *array*, mais tempo se leva para os mover, e mais operações em memória.** -À semelhança acontece com `unshift`: para adicionar um elemento ao início do *array*, nós primeiro precisamos de mover os elementos existentes para à direita, e aumentar os seus indices. +A semelhança acontece com `unshift`: para adicionar um elemento ao início do *array*, nós primeiro precisamos de mover os elementos existentes para à direita, aumentando os seus indices. -E, o que se passa com `push/pop`? Eles, não precisam de mover nada. Para extrair um elemento do final, o método `pop` elimina o índice e diminui `length`. +E, o que se passa com `push/pop`? Eles, não precisam de mover nada. Para extrair um elemento do final, o método `pop` limpa o índice e diminui `length`. As ações para a operação `pop`: @@ -277,7 +277,7 @@ O semelhante se passa com o método `push`. ## *Loops* -Uma das velhas formas para percorrer itens de um *array*, é o ciclo (*loop*) `for` sobre os seus indices: +Uma das velhas formas para percorrer itens de um *array*, é o ciclo `for` sobre os seus indices: ```js run let arr = ["Maçã", "Laranja", "Pêra"]; @@ -289,7 +289,7 @@ for (let i = 0; i < arr.length; i++) { } ``` -Mas, para *arrays* existe um outro ciclo, o `for..of`: +Mas, para *arrays* existe ainda um outro ciclo, o `for..of`: ```js run let fruits = ["Maçã", "Laranja", "Ameixa"]; @@ -318,9 +318,9 @@ Mas, na verdade é uma má ideia. Existem potenciais problemas com isso: 1. O ciclo `for..in` itera sobre *todas as propriedades*, não apenas sobre as numéricas. - Existem os objetos chamados de "semelhantes-a-arrays" (*array-like*), no navegador e em outros ambientes, que *se parecem com _arrays_*. Isto é, eles têm as propriedades `length` e indices, mas também podem ter outras propriedades não-numéricas e métodos, que geralmente não precisamos. Contudo, o ciclo `for..in` irá listar todos elas. Assim, se precisarmos de trabalhar com objetos semelhantes-a-arrays, aí essas propriedades "extra" podem constituir um problema. + Existem os objetos chamados de "semelhantes-a-arrays" (*array-like*), no navegador e em outros ambientes, que *se parecem com arrays*. Isto é, eles têm as propriedades `length` e indices, mas também podem ter outras propriedades não-numéricas e métodos, que geralmente não precisamos. Contudo, o ciclo `for..in` irá listar todos elas. Assim, se precisarmos de trabalhar com objetos semelhantes-a-arrays, aí essas propriedades "extra" podem constituir um problema. -2. O laço (*loop*) `for..in` está optimizado para objetos genéricos, não *arrays*, e desta forma é 10-100 vezes mais lento. Claro que ainda é muito rápido. A velocidade pode apenas ser importante em pontos cruciais (*bottlenecks*). Mas, deveríamos estar conscientes desta diferença. +2. O laço (*loop*) `for..in` está optimizado para objetos genéricos, não *arrays*, e desta forma é 10-100 vezes mais lento. Claro que ainda assim é muito rápido. A velocidade pode apenas ser importante em pontos cruciais (*bottlenecks*). Mas, deveríamos estar conscientes desta diferença. Em geral, não deveríamos usar `for..in` para *arrays*. @@ -379,8 +379,6 @@ alert( arr[0] ); // 'undefined!' nenhum elemento. alert( arr.length ); // comprimento 2 ``` -No código acima, `new Array(number)` tem todos os elementos como `undefined`. - Para evitar tais surpresas, nós geralmente utilizamos parênteses retos, a não ser que realmente saibamos o que estamos a fazer. ## *Arrays* multidimensionais @@ -461,9 +459,9 @@ alert( 0 == [] ); // true alert('0' == [] ); // false ``` -Aqui, em ambos os casos, nós comparamos um primitivo a um objeto *array*. Portanto, o *array* `[]` é convertido para primitivo para os propósitos da comparação e se transforma numa *string* vazia `''`. +Aqui, em ambos os casos, nós comparamos um primitivo a um objeto *array*. Assim, o *array* `[]` é convertido para primitivo para os propósitos da comparação e se transforma numa *string* vazia `''`. -Então, a comparação continua entre primitivos, como é descrito no capítulo : +Então, a comparação continua entre primitivos, como é descrita no capítulo : ```js run // depois de [] ser convertido para '' From d3e4e967d3a73f1a1f260610db0812b41f3bef09 Mon Sep 17 00:00:00 2001 From: Osvaldo Dias dos Santos Date: Tue, 31 Jan 2023 20:14:03 +0100 Subject: [PATCH 4/8] Update "Arrays" translation (1) --- 1-js/05-data-types/04-array/1-item-value/solution.md | 2 +- 1-js/05-data-types/04-array/1-item-value/task.md | 3 ++- 1-js/05-data-types/04-array/10-maximal-subarray/solution.md | 2 +- 1-js/05-data-types/04-array/2-create-array/task.md | 4 ++-- 1-js/05-data-types/04-array/3-call-array-this/solution.md | 4 ++-- 1-js/05-data-types/04-array/3-call-array-this/task.md | 2 +- 1-js/05-data-types/04-array/5-array-input-sum/solution.md | 2 +- 1-js/05-data-types/04-array/5-array-input-sum/task.md | 6 +++--- 8 files changed, 13 insertions(+), 12 deletions(-) diff --git a/1-js/05-data-types/04-array/1-item-value/solution.md b/1-js/05-data-types/04-array/1-item-value/solution.md index 1c80ccff7..d9842e3c6 100644 --- a/1-js/05-data-types/04-array/1-item-value/solution.md +++ b/1-js/05-data-types/04-array/1-item-value/solution.md @@ -2,7 +2,7 @@ O resultado é `4`: ```js run -let fruits = ["Maçã", "Pêra", "Laranja"]; +let fruits = ["Maçã", "Pera", "Laranja"]; let shoppingCart = fruits; diff --git a/1-js/05-data-types/04-array/1-item-value/task.md b/1-js/05-data-types/04-array/1-item-value/task.md index bec34fe5f..9a8715ae9 100644 --- a/1-js/05-data-types/04-array/1-item-value/task.md +++ b/1-js/05-data-types/04-array/1-item-value/task.md @@ -7,7 +7,7 @@ importance: 3 O que irá este código mostrar? ```js -let fruits = ["Maçã", "Pêra", "Laranja"]; +let fruits = ["Maçã", "Pera", "Laranja"]; // adicione um novo valor à "cópia" let shoppingCart = fruits; @@ -16,3 +16,4 @@ shoppingCart.push("Banana"); // o que existe em fruits? alert( fruits.length ); // ? ``` + diff --git a/1-js/05-data-types/04-array/10-maximal-subarray/solution.md b/1-js/05-data-types/04-array/10-maximal-subarray/solution.md index 28a6ac669..baeb9fd0a 100644 --- a/1-js/05-data-types/04-array/10-maximal-subarray/solution.md +++ b/1-js/05-data-types/04-array/10-maximal-subarray/solution.md @@ -91,4 +91,4 @@ alert( getMaxSubSum([-1, -2, -3]) ); // 0 O algoritmo requere exatamente 1 passagem pelo *array*, portanto o tempo de complexidade é O(n). -Pode encontrar informação mais detalhada sobre o algoritmo aqui: [Sublista contígua de soma máxima](https://pt.wikipedia.org/wiki/Sublista_cont%C3%ADgua_de_soma_m%C3%A1xima). Se, ainda não for óbvio porque isso funciona, então por favor rasteie cada algoritmo nos exemplos acima e veja como trabalha, é melhor do que quaisquer palavras. +Pode encontrar informação mais detalhada sobre o algoritmo aqui: [Sublista contígua de soma máxima](https://pt.wikipedia.org/wiki/Sublista_cont%C3%ADgua_de_soma_m%C3%A1xima). Se, ainda não for óbvio porque isso funciona, então por favor rasteie o algoritmo nos exemplos acima e veja como trabalha, é melhor do que quaisquer palavras. diff --git a/1-js/05-data-types/04-array/2-create-array/task.md b/1-js/05-data-types/04-array/2-create-array/task.md index 9be6742f8..811005b2d 100644 --- a/1-js/05-data-types/04-array/2-create-array/task.md +++ b/1-js/05-data-types/04-array/2-create-array/task.md @@ -8,7 +8,7 @@ Vamos tentar 5 operações com *arrays*. 1. Crie um *array* `styles` com os itens "Jazz" e "Blues". 2. Adicione "Rock-n-Roll" ao fim. -3. Substitua o valor do meio por "Clássicos". O seu código para encontrar o valor do meio deverá funcionar para quaisquer *arrays* com um comprimento ímpar. +3. Substitua o valor do meio por "Clássicos". O seu código, para encontrar o valor do meio, deverá funcionar para quaisquer *arrays* com um comprimento ímpar. 4. Elimine o primeiro valor do *array* e o mostre. 5. Adicione `Rap` e `Reggae` ao inicio do *array*. @@ -16,7 +16,7 @@ O *array* ao longo do processo: ```js no-beautify Jazz, Blues -Jazz, Bues, Rock-n-Roll +Jazz, Blues, Rock-n-Roll Jazz, Clássicos, Rock-n-Roll Clássicos, Rock-n-Roll Rap, Reggae, Clássicos, Rock-n-Roll diff --git a/1-js/05-data-types/04-array/3-call-array-this/solution.md b/1-js/05-data-types/04-array/3-call-array-this/solution.md index 3574c7dbe..82af1cc9b 100644 --- a/1-js/05-data-types/04-array/3-call-array-this/solution.md +++ b/1-js/05-data-types/04-array/3-call-array-this/solution.md @@ -1,4 +1,4 @@ -A invocação `arr[2]()` é sintáticamente a antiga `obj[method]()`; no papel de `obj` temos `arr`, e no papel de `method` temos `2`. +A chamada `arr[2]()` é sintaticamente a antiga `obj[method]()`; no papel de `obj` temos `arr`, e no papel de `method` temos `2`. Assim, temos uma chamada da função `arr[2]` como um método de objeto. Naturalmente, como ela recebe em `this` a referência ao objeto `arr`, ela exibe o *array*: @@ -12,4 +12,4 @@ arr.push(function() { arr[2](); // a,b,function(){...} ``` -O *array* tem 3 valores: inicialmente dois, mais a função. +O *array* tem 3 valores: inicialmente tinha dois, e a função foi adicionada. diff --git a/1-js/05-data-types/04-array/3-call-array-this/task.md b/1-js/05-data-types/04-array/3-call-array-this/task.md index f20645101..9d707c1e6 100644 --- a/1-js/05-data-types/04-array/3-call-array-this/task.md +++ b/1-js/05-data-types/04-array/3-call-array-this/task.md @@ -2,7 +2,7 @@ importance: 5 --- -# Invocando o contexto de um *array* +# Chamando uma função no contexto de um *array* Qual é o resultado? Porquê? diff --git a/1-js/05-data-types/04-array/5-array-input-sum/solution.md b/1-js/05-data-types/04-array/5-array-input-sum/solution.md index 5264a9ed6..68067ab23 100644 --- a/1-js/05-data-types/04-array/5-array-input-sum/solution.md +++ b/1-js/05-data-types/04-array/5-array-input-sum/solution.md @@ -1,4 +1,4 @@ -Por favor repare no subtítulo, e em detalhes importantes da solução. Nós não convertemos `value` para número imediatamente após `prompt`, porque depois de `value = +value` não teríamos como ver a diferença entre uma *string* vazia (o sinal para parar) e zero (um número válido). Assim, nós o fazemos mais tarde. +Por favor repare nos subtis, mas importantes detalhes da solução. Nós não convertemos `value` para número imediatamente após `prompt`, porque depois de `value = +value` não teríamos como ver a diferença entre uma *string* vazia (o sinal para parar) e zero (um número válido). Assim, nós o fazemos mais tarde. ```js run demo diff --git a/1-js/05-data-types/04-array/5-array-input-sum/task.md b/1-js/05-data-types/04-array/5-array-input-sum/task.md index 28909e4dc..5567a77d3 100644 --- a/1-js/05-data-types/04-array/5-array-input-sum/task.md +++ b/1-js/05-data-types/04-array/5-array-input-sum/task.md @@ -2,12 +2,12 @@ importance: 4 --- -# Some números inseridos +# Some números entrados pelo usuário Escreva a função `sumInput()` que: -- Peça ao utilizador por valores usando `prompt` e guarde os valores num *array*. -- Não peça mais quando o utilizador inserir um valor não-numérico, uma *string* vazia, ou pressione "*Cancel*". +- Peça ao usuário por valores usando `prompt`, e os guarde num *array*. +- Não peça mais quando o utilizador fornecer um valor não-numérico, uma *string* vazia, ou pressione "*Cancel*". - Calcule e retorne a soma dos itens no *array*. P.S. Um zero `0` é um número válido, por favor não pare de pedir com zero. From a16e14137d342821e5f79a24c2a3f181b41aeefd Mon Sep 17 00:00:00 2001 From: Osvaldo Dias dos Santos Date: Wed, 1 Feb 2023 21:00:43 +0100 Subject: [PATCH 5/8] Update "Arrays" translation (2) --- 1-js/05-data-types/04-array/article.md | 46 ++++++++++++++++++++++---- 1 file changed, 39 insertions(+), 7 deletions(-) diff --git a/1-js/05-data-types/04-array/article.md b/1-js/05-data-types/04-array/article.md index 0a6e52d91..b61beb443 100644 --- a/1-js/05-data-types/04-array/article.md +++ b/1-js/05-data-types/04-array/article.md @@ -17,7 +17,7 @@ let arr = new Array(); let arr = []; ``` -Quase sempre é usada a segunda sintaxe. Também podemos fornecer elementos iniciais entre os parênteses: +Quase sempre é usada a segunda sintaxe. Também podemos fornecer elementos iniciais entre os parênteses retos: ```js let fruits = ["Maçã", "Laranja", "Ameixa"]; @@ -25,7 +25,7 @@ let fruits = ["Maçã", "Laranja", "Ameixa"]; Os elementos de um *array* são numerados, começando por zero. -Podemos obter um elemento pelo seu número entre parênteses retos: +Podemos obter um elemento fornecendo a sua posição entre parênteses retos: ```js run let fruits = ["Maçã", "Laranja", "Ameixa"]; @@ -38,16 +38,16 @@ alert( fruits[2] ); // Ameixa Podemos substituir um elemento: ```js -fruits[2] = 'Pêra'; // now ["Maçã", "Laranja", "Pêra"] +fruits[2] = 'Pera'; // now ["Maçã", "Laranja", "Pera"] ``` ...Ou adicionar um novo ao *array*: ```js -fruits[3] = 'Limão'; // now ["Maçã", "Laranja", "Pêra", "Limão"] +fruits[3] = 'Limão'; // now ["Maçã", "Laranja", "Pera", "Limão"] ``` -O número total dos elementos no *array* é o seu `*length*` (comprimento): +O número total dos elementos no *array* é o seu comprimento (`*length*`): ```js run let fruits = ["Maçã", "Laranja", "Ameixa"]; @@ -92,13 +92,45 @@ let fruits = [ O estilo de "vírgula final" torna mais fácil inserir/remover itens, porque todas as linhas se tornam semelhantes. ```` +## Obtenha o último elemento com "at" + +[recent browser="new"] + +Digamos que queremos o último elemento do *array* + +Algumas linguagens de programação permitem o uso de indices negativos para este propósito, como `fruits[-1]`. + +Mas, em JavaScript isto não funciona. O resultado irá ser `undefined`, porque um índice entre parenteses retos é tratado literalmente. + +Podemos explicitamente calcular o índice do último elemento, e depois o aceder: `fruits[fruits.length - 1]`. + +```js run +let fruits = ["Maçã", "Laranja", "Ameixa"]; + +alert( fruits[fruits.length-1] ); // Ameixa +``` + +Um pouco complicado, não? Nós precisamos de escrever o nome da variável duas vezes. + +Felizmente, existe uma sintaxe mais curta: `fruits.at(-1)`: + +```js run +let fruits = ["Maçã", "Laranja", "Ameixa"]; + +// o mesmo que fruits[fruits.length-1] +alert( fruits.at(-1) ); // Ameixa +``` + +Por outras palavras, `arr.at(i)`: +- é exatamente o mesmo que `arr[i]`, se `i >= 0`. +- para valores negativos de `i`, a procura começa do fim do *array*. ## Métodos pop/push, shift/unshift -Uma [queue](https://en.wikipedia.org/wiki/Queue_(abstract_data_type)) (*fila*) é um dos usos mais comuns de um *array*. Em ciência dos computadores, isto significa uma coleção ordenada de elementos que suporta duas operações: +Uma *fila* ([queue](https://en.wikipedia.org/wiki/Queue_(abstract_data_type))) é um dos usos mais comuns para um *array*. Em ciência dos computadores, ela significa uma coleção ordenada de elementos que suporta duas operações: - `push` adiciona um elemento ao final. -- `shift` obtém um elemento do início, avançando a fila, de modo que o 2º elemento se torne no 1º. +- `shift` obtém um elemento do início, avançando a fila, de modo que o 2º elemento se torna no 1º. ![](queue.svg) From ac385c3d347e9c2755179d3a8ed75d82acd4fa3b Mon Sep 17 00:00:00 2001 From: Osvaldo Dias dos Santos Date: Wed, 1 Feb 2023 21:19:22 +0100 Subject: [PATCH 6/8] Update "Arrays" translation (2) --- 1-js/05-data-types/04-array/article.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/1-js/05-data-types/04-array/article.md b/1-js/05-data-types/04-array/article.md index b61beb443..c838149c7 100644 --- a/1-js/05-data-types/04-array/article.md +++ b/1-js/05-data-types/04-array/article.md @@ -47,7 +47,7 @@ fruits[2] = 'Pera'; // now ["Maçã", "Laranja", "Pera"] fruits[3] = 'Limão'; // now ["Maçã", "Laranja", "Pera", "Limão"] ``` -O número total dos elementos no *array* é o seu comprimento (`*length*`): +O número total dos elementos no *array* é o seu comprimento (`length`): ```js run let fruits = ["Maçã", "Laranja", "Ameixa"]; From bc384e5253601b3eda826b9bb5d050f6e8c7f181 Mon Sep 17 00:00:00 2001 From: Osvaldo Dias dos Santos Date: Thu, 2 Feb 2023 21:13:18 +0100 Subject: [PATCH 7/8] Update "Arrays" translation (3) --- 1-js/05-data-types/04-array/article.md | 54 +++++++++++++------------- 1 file changed, 28 insertions(+), 26 deletions(-) diff --git a/1-js/05-data-types/04-array/article.md b/1-js/05-data-types/04-array/article.md index c838149c7..91533c99b 100644 --- a/1-js/05-data-types/04-array/article.md +++ b/1-js/05-data-types/04-array/article.md @@ -145,7 +145,7 @@ Ela suporta duas operações: - `push` adiciona um elemento ao final. - `pop` toma um elemento do final. -Assim, novos elementos são adicionados ou tomados sempre ao/do "final". +Assim, novos elementos são sempre adicionados ou tomados do "final". Uma pilha (*stack*) é geralmente ilustrada como um baralho de cartas: novas cartas são adicionadas ao topo ou tiradas do topo: @@ -153,61 +153,63 @@ Uma pilha (*stack*) é geralmente ilustrada como um baralho de cartas: novas car Para pilhas, o último item inserido é recebido primeiro, o que também é chamado de princípio *LIFO* (*Last-In-First-Out*) (o-Último-a-Entrar-é-o-Primeiro-a-Sair). Para filas (*queues*), nós temos *FIFO* (*First-In-First-Out*) (o-Primeiro-a-Entrar-é-o-Primeiro-a-Sair). -Os *arrays* em JavaScript tanto podem trabalhar como uma fila, como também uma pilha. Eles permitem-lhe adicionar/remover elementos quer ao/do início como ao/do final. +Os *arrays* em JavaScript tanto podem trabalhar como uma fila, ou como uma pilha. Eles permitem-lhe adicionar/remover elementos quer ao/do início como ao/do final. -Em ciência dos computadores, a estrutura de dados que permite isto é chamada de [deque](https://pt.wikipedia.org/wiki/Deque_(estruturas_de_dados)). +Em ciência dos computadores, a estrutura de dados que permite isto é chamada [deque](https://pt.wikipedia.org/wiki/Deque_(estruturas_de_dados)). **Métodos que trabalham no final do _array_:** -`*pop*` +`pop` : Extrai o último elemento do *array* e o retorna: ```js run - let fruits = ["Maçã", "Laranja", "Pêra"]; + let fruits = ["Maçã", "Laranja", "Pera"]; - alert( fruits.pop() ); // remove "Pêra" e o exibe + alert( fruits.pop() ); // remove "Pera" e exibe alert( fruits ); // Maçã, Laranja ``` -`*push*` +Ambos, `fruits.pop()` e `fruits.at(-1)` retornam o último elemento do *array*, mas `fruits.pop()` adicionalmente modifica o *array* removendo-o. + +`push` : Adiciona o elemento ao final do *array*: ```js run let fruits = ["Maçã", "Laranja"]; - fruits.push("Pêra"); + fruits.push("Pera"); - alert( fruits ); // Maçã, Laranja, Pêra + alert( fruits ); // Maçã, Laranja, Pera ``` A chamada `fruits.push(...)` é igual a `fruits[fruits.length] = ...`. **Métodos que trabalham no início do _array_:** -`*shift*` +`shift` : Extrai o primeiro elemento do *array* e o retorna: ```js - let fruits = ["Maçã", "Laranja", "Pêra"]; + let fruits = ["Maçã", "Laranja", "Pera"]; - alert( fruits.shift() ); // remove Maçã e o exibe + alert( fruits.shift() ); // remove Maçã e exibe - alert( fruits ); // Laranja, Pêra + alert( fruits ); // Laranja, Pera ``` -`*unshift*` +`unshift` : Adiciona o elemento ao início do *array*: ```js - let fruits = ["Laranja", "Pêra"]; + let fruits = ["Laranja", "Pera"]; fruits.unshift('Maçã'); - alert( fruits ); // Maçã, Laranja, Pêra + alert( fruits ); // Maçã, Laranja, Pera ``` -Os métodos `*push*` e `*unshift*` podem adicionar múltiplos elementos de uma só vez: +Os métodos `push` e `unshift` podem adicionar múltiplos elementos de uma só vez: ```js run let fruits = ["Maçã"]; @@ -236,32 +238,32 @@ let arr = fruits; // cópia por referência (duas variáveis referenciam o mesmo alert( arr === fruits ); // true (verdadeiro) -arr.push("Pêra"); // modifique o array por referência +arr.push("Pera"); // modifique o array por referência -alert( fruits ); // Banana, Pêra - 2 itens agora +alert( fruits ); // Banana, Pera - 2 itens agora ``` -...Mas, o que torna os *arrays* realmente especiais é a sua representação interna. O interpretador de JavaScript tenta armazenar os seus elementos numa área contígua de memória, um após outro, precisamente como mostrado nas ilustrações deste capítulo, e existem também outras optimizações para fazerem os *arrays* trabalhar verdadeiramente rápido. +...Mas, o que torna os *arrays* realmente especiais é a sua representação interna. O interpretador de JavaScript tenta armazenar os seus elementos numa área contígua de memória, um após outro, precisamente como mostrado nas ilustrações deste capítulo, e também existem outras optimizações para fazer os *arrays* trabalhar verdadeiramente rápido. -Mas, todas elas quebram se pararmos de trabalhar com um *array* como uma "coleção ordenada", e começarmos a trabalhar com ele como se fosse um objeto regular. +Mas, todas elas quebram se pararmos de trabalhar com um *array* como com uma "coleção ordenada", e começarmos a trabalhar com ele como se fosse um objeto regular. Por exemplo, tecnicamente nós podemos fazer isto: ```js let fruits = []; // cria um array -fruits[99999] = 5; // atribui uma propriedade com um índice muito maior do que o seu comprimento +fruits[99999] = 5; // atribui uma propriedade com um índice muito maior do que o comprimento do *array* fruits.age = 25; // cria uma propriedade com um nome arbitrário ``` -Isso é possível, porque *arrays* são objetos na sua base. Podemos adicionar qualquer propriedade a eles. +Isso é possível, porque *arrays* são objetos na sua base. Podemos adicionar quaisquer propriedades a eles. Mas, o interpretador irá ver que nós estamos a trabalhar com o *array* como com um objeto regular. Optimizações especificas para *arrays* não são adequadas a tais casos e serão desativadas, os seus benefícios desaparecem. Formas de má utilização de um *array*: -- Adicionar uma propriedade não-numérica como `arr.test = 5`. +- Adicionar uma propriedade não-numérica, como `arr.test = 5`. - Formar buracos, como: adicionar `arr[0]` e depois `arr[1000]` (e nada entre eles). - Preencher o *array* por ordem inversa, como `arr[1000]`, `arr[999]` e assim por diante. @@ -273,13 +275,13 @@ Os métodos `push/pop` correm rápidamente, enquanto `shift/unshift` são lentos ![](array-speed.svg) -Porque é mais rápido trabalhar no final de um *array*, do que no seu início? Vejamos o que acontece durante a execução: +Porque é mais rápido trabalhar no final de um *array*, do que no seu início? Vejamos o que acontece durante a execução: ```js fruits.shift(); // tome 1 elemento do início ``` -Não é suficiente tomar e remover o elemento com o número `0`. Os outros elementos também precisam de ser renumerados. +Não é suficiente tomar e remover o elemento com o índice `0`. Os outros elementos também precisam de ser reposicionados. A operação `shift` deve efetuar 3 coisas: From c88c15c490e7e30e1b19da6e073cb68fcc7b3b69 Mon Sep 17 00:00:00 2001 From: Osvaldo Dias dos Santos Date: Fri, 3 Feb 2023 20:57:13 +0100 Subject: [PATCH 8/8] Update "Arrays" translation (4) --- 1-js/05-data-types/04-array/article.md | 57 ++++++++++++++------------ 1 file changed, 31 insertions(+), 26 deletions(-) diff --git a/1-js/05-data-types/04-array/article.md b/1-js/05-data-types/04-array/article.md index 91533c99b..43eaba06c 100644 --- a/1-js/05-data-types/04-array/article.md +++ b/1-js/05-data-types/04-array/article.md @@ -96,7 +96,7 @@ O estilo de "vírgula final" torna mais fácil inserir/remover itens, porque tod [recent browser="new"] -Digamos que queremos o último elemento do *array* +Digamos que queremos o último elemento do *array*. Algumas linguagens de programação permitem o uso de indices negativos para este propósito, como `fruits[-1]`. @@ -123,7 +123,7 @@ alert( fruits.at(-1) ); // Ameixa Por outras palavras, `arr.at(i)`: - é exatamente o mesmo que `arr[i]`, se `i >= 0`. -- para valores negativos de `i`, a procura começa do fim do *array*. +- para valores negativos de `i`, a procura começa pelo fim do *array*. ## Métodos pop/push, shift/unshift @@ -227,7 +227,7 @@ Um *array* é um tipo especial de objeto. Os parêntesis retos usados para acede Eles são uma extensão aos objetos, fornecendo métodos especiais para trabalhar com coleções ordenadas de dados e também a propriedade `length`. Assim, no seu núcleo um *array* é um objeto. -Lembre-se, só existem oito tipos de dados básicos em JavaScript (veja o capítulo [Tipos de dads](info:types) para mais informação). O *array* é um objeto e portanto comporta-se como um objeto. +Lembre-se, só existem oito tipos de dados básicos em JavaScript (veja o capítulo [Tipos de dads](info:types) para mais informação). O *array* é um objeto, e portanto comporta-se como um objeto. Por exemplo, ele é copiado por referência: @@ -243,7 +243,7 @@ arr.push("Pera"); // modifique o array por referência alert( fruits ); // Banana, Pera - 2 itens agora ``` -...Mas, o que torna os *arrays* realmente especiais é a sua representação interna. O interpretador de JavaScript tenta armazenar os seus elementos numa área contígua de memória, um após outro, precisamente como mostrado nas ilustrações deste capítulo, e também existem outras optimizações para fazer os *arrays* trabalhar verdadeiramente rápido. +...Mas, o que torna os *arrays* realmente especiais é a sua representação interna. O interpretador de JavaScript tenta armazenar os seus elementos numa área contígua de memória, um após outro, precisamente como mostrado nas ilustrações deste capítulo, e também existem outras optimizações para fazerem os *arrays* trabalhar verdadeiramente rápido. Mas, todas elas quebram se pararmos de trabalhar com um *array* como com uma "coleção ordenada", e começarmos a trabalhar com ele como se fosse um objeto regular. @@ -267,11 +267,11 @@ Formas de má utilização de um *array*: - Formar buracos, como: adicionar `arr[0]` e depois `arr[1000]` (e nada entre eles). - Preencher o *array* por ordem inversa, como `arr[1000]`, `arr[999]` e assim por diante. -Por favor, pense em *arrays* como estruturas especiais para trabalhar com *dados ordenados*. Eles fornecem métodos especiais para isso. *Arrays* são cuidadosamente afinados dentro dos interpretadores de JavaScript (*JavaScript engines*) para trabalharem com dados ordenados contíguos, por favor os utilize dessa forma. E, se precisar de chaves arbitrárias, são altas as chances de que na verdade necessite de um objeto regular `{}`. +Por favor, pense em *arrays* como estruturas especiais para trabalhar com *dados ordenados*. Eles fornecem métodos especiais para isso. *Arrays* são cuidadosamente afinados dentro dos interpretadores de JavaScript (*JavaScript engines*) para trabalharem com dados ordenados contíguos, por favor os utilize desta forma. E, se precisar de chaves arbitrárias, são altas as chances de que na verdade necessite de um objeto regular `{}`. ## Performance -Os métodos `push/pop` correm rápidamente, enquanto `shift/unshift` são lentos. +Os métodos `push/pop` correm rapidamente, enquanto `shift/unshift` são lentos. ![](array-speed.svg) @@ -293,7 +293,7 @@ A operação `shift` deve efetuar 3 coisas: **Quantos mais elementos no *array*, mais tempo se leva para os mover, e mais operações em memória.** -A semelhança acontece com `unshift`: para adicionar um elemento ao início do *array*, nós primeiro precisamos de mover os elementos existentes para à direita, aumentando os seus indices. +A semelhança acontece com `unshift`: para adicionar um elemento ao início do *array*, nós primeiro precisamos de mover os elementos existentes para a direita, aumentando os seus indices. E, o que se passa com `push/pop`? Eles, não precisam de mover nada. Para extrair um elemento do final, o método `pop` limpa o índice e diminui `length`. @@ -314,7 +314,7 @@ O semelhante se passa com o método `push`. Uma das velhas formas para percorrer itens de um *array*, é o ciclo `for` sobre os seus indices: ```js run -let arr = ["Maçã", "Laranja", "Pêra"]; +let arr = ["Maçã", "Laranja", "Pera"]; *!* for (let i = 0; i < arr.length; i++) { @@ -339,12 +339,12 @@ O `for..of` não dá acesso ao índice do elemento atual, mas apenas ao seu valo Tecnicamente, uma vez que *arrays* são objetos, também é possível usar `for..in`: ```js run -let arr = ["Maçã", "Laranja", "Pêra"]; +let arr = ["Maçã", "Laranja", "Pera"]; *!* for (let key in arr) { */!* - alert( arr[key] ); // Maçã, Laranja, Pêra + alert( arr[key] ); // Maçã, Laranja, Pera } ``` @@ -352,9 +352,9 @@ Mas, na verdade é uma má ideia. Existem potenciais problemas com isso: 1. O ciclo `for..in` itera sobre *todas as propriedades*, não apenas sobre as numéricas. - Existem os objetos chamados de "semelhantes-a-arrays" (*array-like*), no navegador e em outros ambientes, que *se parecem com arrays*. Isto é, eles têm as propriedades `length` e indices, mas também podem ter outras propriedades não-numéricas e métodos, que geralmente não precisamos. Contudo, o ciclo `for..in` irá listar todos elas. Assim, se precisarmos de trabalhar com objetos semelhantes-a-arrays, aí essas propriedades "extra" podem constituir um problema. + Existem os objetos chamados de "semelhantes-a-arrays" (*array-like*), no navegador e em outros ambientes, que *se parecem com arrays*. Isto é, eles têm as propriedades `length` e indices, mas também podem ter outras propriedades não-numéricas e métodos, que geralmente não precisamos. Contudo, o ciclo `for..in` irá listar todas elas. Assim, se precisarmos de trabalhar com objetos semelhantes-a-arrays, aí essas propriedades "extra" podem constituir um problema. -2. O laço (*loop*) `for..in` está optimizado para objetos genéricos, não *arrays*, e desta forma é 10-100 vezes mais lento. Claro que ainda assim é muito rápido. A velocidade pode apenas ser importante em pontos cruciais (*bottlenecks*). Mas, deveríamos estar conscientes desta diferença. +2. O laço (*loop*) `for..in` está optimizado para objetos genéricos, não *arrays*, e desta forma é 10-100 vezes mais lento. Claro que ainda assim é muito rápido. A velocidade pode apenas ser importante em pontos cruciais (*bottlenecks*). Mas, devemos estar conscientes desta diferença. Em geral, não deveríamos usar `for..in` para *arrays*. @@ -372,7 +372,7 @@ fruits[123] = "Maçã"; alert( fruits.length ); // 124 ``` -Note que geralmente nós não usamos *arrays* dessa forma. +Note que geralmente nós não usamos *arrays* desta forma. Uma outra coisa interessante sobre a propriedade `length`, é que pode ser alterada. @@ -396,12 +396,12 @@ Assim, a forma mais simples para limpar um array é: `arr.length = 0;`. Há mais uma sintaxe para se criar um *array*: ```js -let arr = *!*new Array*/!*("Maçã", "Pêra", "etc"); +let arr = *!*new Array*/!*("Maçã", "Pera", "etc"); ``` Raramente é usada, porque os parênteses retos são mais curtos `[]`. Além disso, existe uma característica peculiar a acompanhá-la. -Se `new Array` for chamada com um único argumento e sendo este numérico, então ela cria um *array* *sem itens, mas com esse comprimento*. +Se `new Array` for chamada com um único argumento e sendo este numérico, então ela cria um *array* *sem itens, mas com esse comprimento*. Vejamos como alguém pode se atraiçoar a si próprio: @@ -429,7 +429,7 @@ let matrix = [ alert( matrix[1][1] ); // o elemento central ``` -## *toString* +## toString Os *arrays* têm a sua própria implementação do método `toString`, que retorna uma lista de elementos separados por vírgulas. @@ -475,7 +475,7 @@ Vamos nos recordar das regras: A comparação exata (*strict*) `===` é ainda mais simples, porque ela não converte tipos. -Assim, se nós compararmos *arrays* com `==`, eles nunca são iguais, a não ser que estejamos a comparar duas variáveis que referenciam exatamente o mesmo *array*. +Assim, se nós compararmos *arrays* com `==`, eles nunca são iguais, a não ser que comparemos duas variáveis que referenciam exatamente o mesmo *array*. Por exemplo: ```js run @@ -501,7 +501,7 @@ Então, a comparação continua entre primitivos, como é descrita no capítulo // depois de [] ser convertido para '' alert( 0 == '' ); // true, como '' é convertida para 0 -alert('0' == '' ); // false, nenhuma conversão de tipos de dados, só strings diferentes +alert('0' == '' ); // false, nenhuma conversão de tipos de dados, apenas strings diferentes ``` Então, como comparar *arrays*? @@ -512,21 +512,26 @@ Isto é simples: não use o operador `==`. Em vez disto, os compare item-por-ite O *array* é um tipo especial de objeto, apropriado para armazenar e gerir itens de dados ordenados. -- A declaração: +A declaração: - ```js - // parênteses retos (usual) - let arr = [item1, item2...]; +```js +// parênteses retos (usual) +let arr = [item1, item2...]; - // new Array (excepcionalmente rara) - let arr = new Array(item1, item2...); - ``` +// new Array (excepcionalmente rara) +let arr = new Array(item1, item2...); +``` - A chamada a `new Array(number)` cria um *array* com o comprimento dado, mas sem elementos. +A chamada a `new Array(number)` cria um *array* com o comprimento dado, mas sem elementos. - A propriedade `length` é o comprimento do *array* ou, para ser preciso, o seu último índice numérico mais um. Ela é auto-ajustada por métodos do *array*. - Se nós encurtarmos `length` manualmente, o *array* é truncado. +Obtendo os elementos: + +- nós podemos obter o elemento por meio do seu índice, como `arr[0]` +- também podemos usar o método `at(i)`, que permite indices negativos. Para valores negativos de `i`, a procura começa pelo fim do array. Se `i >= 0`, funciona como `arr[i]`. + Podemos usar um *array* como uma *deque* (estrutura de dados), com as seguintes operações: - `push(...items)` adiciona `items` ao final.