Skip to content

Commit 809b184

Browse files
committed
Merge pull request braziljs#265 from joaostein/traducaoCap4
Adiciona tradução Capítulo 04 até linha 769
2 parents 345fc20 + 42913a8 commit 809b184

File tree

1 file changed

+102
-1
lines changed

1 file changed

+102
-1
lines changed

chapters/04-estruturas-de-dados.md

Lines changed: 102 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -665,4 +665,105 @@ Pode ser útil usar um valor de incremento diferente do valor padrão (por exemp
665665

666666
Os arrays possuem o método `reverse`, que modifica o array invertendo a ordem que os elementos aparecem. Para esse exercício, escreva duas funções: `reverseArray` e `reverseArrayInPlace`. A primeira (`reverseArray`) recebe um array como argumento e produz um _novo_ array que tem os mesmos elementos com ordem inversa. A segunda (`reverseArrayInPlace`) funciona da mesma forma que o método `reverse`, invertendo seus elementos apenas modificando o array que foi fornecido como argumento. Ambas as funções não devem usar o método padrão `reverse`.
667667

668-
http://eloquentjavascript.net/04_data.html#p_0ysB6LgssH
668+
Levando em consideração as notas sobre efeitos colaterais e funções puras do [capítulo anterior](./03-funcoes.md), qual variante você espera que seja útil em mais situações? Qual delas é mais eficiente?
669+
670+
```js
671+
// Your code here.
672+
673+
console.log(reverseArray(["A", "B", "C"]));
674+
// → ["C", "B", "A"];
675+
var arrayValue = [1, 2, 3, 4, 5];
676+
reverseArrayInPlace(arrayValue);
677+
console.log(arrayValue);
678+
// → [5, 4, 3, 2, 1]
679+
```
680+
681+
**Dicas**
682+
683+
Existem duas maneiras óbvias de implementar `reverseArray`. A primeira é simplesmente iterar o array fornecido do início ao fim e usar o método `unshift` para inserir cada elemento no início do novo array. A segunda é iterar o array fornecido do fim ao início e usar o método `push`. Iterar um array de trás para frente faz com que seja necessário usar uma notação `for` um pouco estranha (`var i = array.length - 1; i >= 0; i--`).
684+
685+
Inverter o array em questão (`reverseArrayInPlace`) é mais difícil. Você deve ter cuidado para não sobrescrever elementos que você precisará posteriormente. Usar `reverseArray` ou até mesmo copiar o array inteiro (`array.slice(0)` é uma boa forma de se copiar um array) funciona mas é considerado trapaça.
686+
687+
O truque é _inverter_ o primeiro e o último elemento, depois o segundo e o penúltimo e assim por diante. Você pode fazer isso percorrendo até a metade do valor de `length` do array (use `Math.floor` para arredondar o valor para baixo — você não precisa usar o elemento do meio de um array com tamanho ímpar) e substituir o elemento na posição `i` com o elemento na posição `array.length - 1 - i`. Você pode usar uma variável local para armazenar temporariamente um dos elementos, sobrescrever o seu valor com o valor do elemento espelhado (elemento que deseja substituir), e por fim, colocar o valor da variável local no lugar onde o elemento espelhado estava originalmente.
688+
689+
### A lista
690+
691+
Objetos como agrupamentos genéricos de valores, podem ser usados para construir diversos tipos de estrutura de dados. Uma estrutura de dado comum é a _lista_ (não se confunda com o array). A lista é um conjunto de objetos, sendo que o primeiro objeto contém uma referência para o segundo, o segundo para o terceiro, e assim por diante.
692+
693+
```js
694+
var list = {
695+
value: 1,
696+
rest: {
697+
value: 2,
698+
rest: {
699+
value: 3,
700+
rest: null
701+
}
702+
}
703+
};
704+
```
705+
706+
O resultado desses objetos forma uma corrente, como representado abaixo:
707+
708+
![Linked List](http://eloquentjavascript.net/img/linked-list.svg)
709+
710+
Uma das vantagens das listas é que elas podem compartilhar partes de sua estrutura. Por exemplo, se eu criasse dois novos valores `{value: 0, rest: list}` e `{value: -1, rest: list}` (sendo que `list` é uma referência à variável definida anteriormente), ambas serão listas independentes que compartilham a mesma estrutura que foi usada para criar os três últimos elementos. Além disso, a lista original ainda é uma lista válida com três elementos.
711+
712+
Escreva a função `arrayToList` que constrói uma estrutura de dados similar à estrutura anterior quando fornecido `[1, 2, 3]` como argumento e, escreva também, a função `listToArray` que produz um array quando dado uma lista. Além disso, implemente uma função auxiliar `prepend` que receberá um elemento e uma lista e será responsável por criar uma nova lista com esse novo elemento adicionado ao início da lista original e, por fim, crie a função `nth` que recebe uma lista e um número como argumentos e retorna o elemento que está na posição informada pelo número ou `undefined` caso não exista elemento em tal posição.
713+
714+
Caso não tenha feito, implemente a versão recursiva da função `nth`.
715+
716+
```js
717+
// Your code here.
718+
719+
console.log(arrayToList([10, 20]));
720+
// → {value: 10, rest: {value: 20, rest: null}}
721+
console.log(listToArray(arrayToList([10, 20, 30])));
722+
// → [10, 20, 30]
723+
console.log(prepend(10, prepend(20, null)));
724+
// → {value: 10, rest: {value: 20, rest: null}}
725+
console.log(nth(arrayToList([10, 20, 30]), 1));
726+
// → 20
727+
```
728+
729+
**Dicas**
730+
731+
Construir uma lista é mais fácil de ser feito de trás para frente. Portanto, `arrayToList` poderia percorrer o array de trás para frente (veja o exercício anterior) e, para cada elemento, adicionar um objeto à lista. Você pode usar uma variável local para armazenar a parte da lista que foi criada e usar um padrão similar a `list = {value: X, rest: list}` para adicionar um elemento.
732+
733+
Para percorrer uma lista (no caso de `listToArray` e `nth`), o seguinte loop `for` pode ser usado:
734+
735+
```js
736+
for (var node = list; node; node = node.rest) {}
737+
```
738+
739+
Você consegue ver como funciona? A cada iteração do loop, `node` aponta para a próxima sublista e, por isso, o corpo da função pode acessar a propriedade `value` para pegar o elemento atual. Ao final de cada iteração, `node` é atualizado apontando para a próxima sublista. Quando seu valor é `null`, nós chegamos ao final da lista e o loop é finalizado.
740+
741+
A versão recursiva de `nth` irá, similarmente, olhar para uma parte ainda menor do _tail_ (final) da lista e, ao mesmo tempo, fazer a contagem do índice até que chegue a zero, significando que é o ponto no qual pode retornar a propriedade `value` do nó que está sendo verificado. Para pegar o elemento na posição zero de uma lista, você pode simplesmente acessar a propriedade `value` do seu nó _head_ (inicial). Para pegar o elemento `N + 1`, você pega o n-ésimo elemento da lista que está contido na propriedade `rest` da lista em questão.
742+
743+
### Deep comparison
744+
745+
O operador `==` compara objetos pelas suas identidades. Entretanto, algumas vezes você pode preferir comparar os valores das suas propriedades de fato.
746+
747+
Escreva a função `deepEqual` que recebe dois valores e retorna `true` apenas se os valores forem iguais ou se forem objetos que possuem propriedades e valores iguais quando comparados usando uma chamada recursiva de `deepEqual`.
748+
749+
Para saber se a comparação entre duas coisas deve ser feita pela identidade (use o operador `===` para isso) ou pela verificação de suas propriedades, você pode usar o operador `typeof`. Se ele produzir `object` para ambos os valores, você deverá fazer uma comparação "profunda". Entretanto, você deve levar em consideração uma excessão: devido a um acidente histórico, `typeof null` também produz `object`.
750+
751+
```js
752+
// Your code here.
753+
754+
var obj = {here: {is: "an"}, object: 2};
755+
console.log(deepEqual(obj, obj));
756+
// → true
757+
console.log(deepEqual(obj, {here: 1, object: 2}));
758+
// → false
759+
console.log(deepEqual(obj, {here: {is: "an"}, object: 2}));
760+
// → true
761+
```
762+
763+
**Dicas**
764+
765+
O teste para saber se está lidando com um objeto real deverá ser parecido com `typeof x == "object" && x != null`. Tome cuidado para comparar as propriedades apenas quando ambos argumentos forem objetos. Em todos os outros casos, você pode simplesmente retornar imediatamente o resultado da aplicação de `===`.
766+
767+
Use um loop `for/in` para percorrer todas as propriedades. Você precisa verificar se ambos os objetos possuem o mesmo conjunto de propriedades e se essas propriedades têm valores idênticos. O primeiro teste pode ser feito contando a quantidade de propriedades em cada objeto e retornar `false` se forem diferentes. Caso seja o mesmo, percorra todas as propriedades de um objeto e, para cada uma delas, verifique se o outro objeto também a possui. Os valores das propriedades são comparados usando uma chamada recursiva para `deepEqual`.
768+
769+
Para retornar o valor correto da função, é mais fácil retornar imediatamente `false` quando qualquer diferença for encontrada e retornar apenas `true` ao final da função.

0 commit comments

Comments
 (0)