Como quebrar um vetor grande em vários menores

Neste artigo veremos duas funções que leem um vetor e devolvem um outro dividido em pedaços menores. O exemplo será bem simples pois a aplicação é a mesma para 5 o para 5 bilhões de registros. 

A primeira função será genérica e você provavelmente poderá utilizá-la em outras linguagens com pouca ou nenhuma adaptação. Já a segunda é utilizando mais das funções do JavaScript para reduzir o código

Em resumo queremos que um vetor linear seja quebrado em vários pequenos vetores. No meu caso, eu precisava que uma lista de contatos fosse quebrada em diversas listas menores para facilitar o controle e atualização das mesmas.

Iremos de algo assim:

let vetor = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14];

Para algo assim:

let vetor = [[0, 1, 2], 
             [3, 4, 5], 
             [6, 7, 8], 
             [9, 10, 11], 
             [12, 13, 14], 
             [15, 16]];

Como podemos fazer isso? Bom, a primeira forma é a seguinte:

Algoritmo Genérico

  1. Criar a função e inicializar as variáveis. Observe que novoVetor é um vetor com um vetor vazio dentro dele.
    function converterVetor(vetor, tamanho) {
        let novoVetor = [[]];
        let novoIndice = 0;
        let novoIndiceSub = 0;
    }
  2. Criar um laço FOR para adicionar os elementos no novoVetor. Observe que:
    1. Precisamos de um IF para testar a hora de avançar de um sub-vetor para outro.
    2. Dentro deste IF é necessário criar um vetor em branco para que o Javascript saiba o tipo do dado.
    3. No final, você está adicionando o valor dentro de um vetor que está dentro de outro vetor, então é preciso usar [x][y] para adicionar na posição correta.
    for(let indice = 0; indice < vetor.length; indice++){
    
        if(indice % tamanho == 0 && indice != 0){
            novoIndice++;
            novoVetor[novoIndice] = [];
            novoIndiceSub = 0;
        }
    
        novoVetor[novoIndice][novoIndiceSub] = vetor[indice];
        novoIndiceSub++;
    }
  3. Por ultimo, basta retornar o resultado. Veja abaixo o código completo.
    function converterVetor(vetor, tamanho) {
        let novoVetor = [[]];
        let novoIndice = 0;
        let novoIndiceSub = 0;
    
    
        for (let indice = 0; indice < vetor.length; indice++) {
    
            if (indice % tamanho == 0 && indice != 0) {
                novoIndice++;
                novoVetor[novoIndice] = [];
                novoIndiceSub = 0;
            }
    
            novoVetor[novoIndice][novoIndiceSub] = vetor[indice];
            novoIndiceSub++;
        }
    
        return novoVetor;
    }

Usando mais recursos JavaScript

Agora vejamos a mesma função, mas usando mais recursos JavaScript para reduzir um pouco o trabalho.

  1. Iniciaremos de forma muito parecida, mas precisaremos de uma variável a menos
    function converterVetor2(vetor, tamanho) {
        let index = 0;
        let novoVetor = [];
    }
  2. Agora faremos o loop for, mas ao invés de percorremos o loop original de 1 em 1, percorreremos o tamanho que já queremos colocar no sub-vetor.
    1. Dentro do loop, usaremos a função slice() que nos retornará um pedaço do vetor. Sendo ele o tamanho exato do sub-vetor.
    2. Após, adicionamos o subVetor ao novo com o método push() que adiciona um elemento na ultima posição.
    for (index = 0; index < vetor.length; index += tamanho) {
        let subVetor = vetor.slice(index, index + tamanho);
        novoVetor.push(subVetor);
    }
  3. Pronto!! Basta retornar o objeto com o resultado. Segue abaixo o código completo.
    function converterVetor2(vetor, tamanho) {
        let index = 0;
        let novoVetor = [];
    
        for (index = 0; index < vetor.length; index += tamanho) {
            let subVetor = vetor.slice(index, index + tamanho);
            novoVetor.push(subVetor);
        }
    
        return novoVetor;
    }

Conclusão

Como você pode ver, o segundo formato é um pouco menos detalhado, mas utilizando os recursos do JavaScript é possível escrever menos código que ainda é fácil de entender. Por isso que, quando você estuda uma linguagem, é importante conhecer as funções nativas e formas mais inteligentes de trabalhar com seus objetos.

Abertas as inscrições para Code Day II.

A Samsung anunciou que estão abertas as incrições para o Code Day II, evento que será realizado em São Paulo, entre os dias 10 e 24 de agosto, no Espaço OCEAN da USP (Universidade de São Paulo). O curso é presencial e possui duração de oito horas e é direcionado a professores e educadores da rede pública. Podem participar professores e educadores que estiveram no Code Day I. Este curso é uma iniciativa da Samsung em parceria com o LSI-TEC (Laboratório de Sistemas Integráveis Tecnológico). Os encontros irão contemplar conceitos e atividades avançadas em IoT (Internet das Coisas).

O Code Day II faz parte do Code IoT, que é uma plataforma de cursos online e gratuitos disponibilizada pela Samsung a todos os interessados em aprender mais sobre tecnologia. Temas que abordam Aplicações para Dispositivos Móveis, Aprendendo a programar e Objetos Inteligentes Conectados estão disponíveis. Ao final de cada curso, os participantes recebem certificado de conclusão, e os cursos estão disponíveis em português, inglês e espanhol.

Continue lendo “Abertas as inscrições para Code Day II.”

Recursão e a Pilha (Stack)

Se você não é novato em programação, e até aqueles que já fizeram algumas cadeiras/módulos de programação, provavelmente já ouviu os termos recursão e pilha.

Recursão é um método de programação onde o código executa uma função que chama a si mesma um número X de vezes para resolver um problema que apresenta um padrão repetitivo. Ela tem uma funcionalidade muito similar aos loops, mas sem explicitamente mostrar que está fazendo o mesmo trabalho repetidas vezes.

Quais as vantagens de usar recursão?

Essa é uma duvida bem comum, devo iterar? ou usar a recursão? Nos seguintes casos, seria melhor usar a recursão:

  • Reduzir o código e deixar torna-lo mais simples de ler: Para quem não está acostumado isso parece estranho, mas em grande maioria dos casos é possível escrever a mesma lógica com um número menor de linhas, tornando-o mais fácil de entender e debugar.
  • Quando você está trabalhando com uma linguagem funcional: Linguagens funcionais lidam com recursão muito melhor que imperativas. Já as linguagens imperativas lidam com iteração melhor, então leve isso em consideração quando estiver desenvolvendo seu programa ou script
  • A recursão é melhor na travessia de árvores. Este é um pouco mais avançado. Uma versão extremamente simplificada do que isso significa é a seguinte: Uma árvore é uma coleção de objetos que estão ligados um ao outro (imagine folhas em uma árvore conectada por ramos que por sua vez estão conectados a outros ramos até as raízes). Uma das maneiras mais eficientes de percorrer essas árvores ao procurar por uma folha (ou nó) específica é seguir, de maneira recursiva, uma única ramificação até o final dessa ramificação até encontrar o valor que você está procurando.

Exemplos de Recursão

Digamos que queremos criar algo simples, como uma função que faz que calcula a potencia N de um valor X (exemplo 2^3 = 8, X^N = 8).

let valor = potencia(2, 2);
//Exibe o valor 4
console.log(valor);

valor = potencia (2, 3);
//Exibe o valor 8
console.log(valor);

valor = potencia (2, 4);
//Exibe o valor 16
console.log(valor);

Importante: Este é apenas um exemplo, utilizem o objeto Math do JavaScript para esse tipo de calculo.

Poderíamos faze-lo com o Loop For

function potencia(x, n) {
  let result = 1;

  // Multiplica o resultado X N vezes para obter a resposta
  for (let i = 0; i < n; i++) {
    result *= x;
  }

  return result;
}

Console.log(potencia(2, 3) ); // 8

Agora utilizando a recursão

function potencia(x, n) {
  if (n == 1) {
    // Quando n finalmente é 1, não executa mais a recursão para finalizar o calculo
    return x;
  } else {
    //obtém a resposta do próximo pedaço do calculo chamando a função novamente
    let recursao = potencia(x, n - 1)

    return x * recursao;
  }
}

console.log(potencia(2, 3) ); // 8

Então, o que está acontecendo exatamente?

No caso da recursão deste algoritmo, quebramos a lógica em pequenos passos que fazem a multiplicação de X pelo resultado anterior até chegar em um ponto onde não é feita mais a chamada recursiva. Quando isso ocorre, as funções começam a ser retornadas e resolvidas.

No caso do exemplo acima, se fizéssemos 2^3, a ultima recursão ser no n==1 que retornaria 2 para a função anterior. Ela multiplicaria 2 * 2, resultando em quatro e retornaria para a primeira chamada que resultaria em 8 e terminaria a função.

A recursão normalmente possui menos linhas de código

A recursão normalmente é menor que a iteração. Abaixo está o mesmo exemplo que fizemos acima, mas usando o mínimo de comandos, retornos e de linhas possíveis.

function pow(x, n) {
  return (n == 1) ? x : (x * pow(x, n - 1));
}

Pilha

Uma pilha é uma região na memória, que opera no modo First-In-Last-Out, exatamente como a pilha que você deve ter estudado em estrutura de dados. Para cada nova ação que precisa ser executada, esta é “empilhada” e terá que ser processada antes da ação anterior voltar a ser trabalhada.

Note que as pilhas não tem tamanho infinito e quando você cria uma função recursiva muito grande ou mau feita, causará o famoso erro que chamamos de stack-overflow

Para ter uma ideia, execute o seguinte código

let i=0;
function estourarPilha() {
    console.log(i++);
    estourarPilha();
}
estourarPilha();

Para cada navegador os valores serão diferentes, mas eventualmente eles irão parar de funcionar pois você conseguiu quebra-los. Mas fique tranquilo, basta reinicia-lo que tudo voltará ao normal.

Conclusão

Esta foi uma introdução bem básica sobre recursão e a pilha no JavaScript, espero que você tenha aprendido com o exemplo e caso tenha alguma duvida ou sugestão por favor deixe seu comentário abaixo.

Criando a classe pilha com JavaScript

Neste post estarei fazendo uma implementação simples da estrutura de dados conhecida como Pilha utilizando o JavaScript. Apesar da lista JavaScript ser totalmente capaz de simular a pilha, fila, lista, etc… a ideia é focar na teoria e criar do zero uma pilha de nós (nodes) como se a funcionalidade não estivesse disponível.

Como funciona a pilha?

A pilha é um tipo de estrutura de dados que funciona no formato que o último item que foi inserido será o primeiro a ser removido da estrutura (Lifo – Last in, First out). Então quando você adicionar 3 números e quiser remove-los, eles serão removidos na ordem inversa que foram adicionados (terceiro – segundo – primeiro).

Considerações

Algumas considerações na nossa implementação para que não ocorra confusão:

  • A classe do JavaScript ainda não permite declarar propriedades como privadas, por isso usarei _ na frente do nome das propriedades ao qual NÂO deveríamos estar acessando externamente.
  •  Esta é uma implementação para uso acadêmico. Por favor utilize a lista do JavaScript para trabalhar com a pilha em produção (new Array ou []).
  • Alguns trechos de código poderiam ser resumidos em uma única linha, mas foram mantidos quebrados para auxiliar aqueles que estão aprendendo.

Implementação:

Classe e Construtor

Beleza, então vamos começar. A primeira coisa que precisamos é criar a classe e o construtor dela conforme o código abaixo. Para o nome da classe usaremos o termo em português, mas para o resto iremos utilizar os termos em Inglês pois parece ser o padrão mais utilizado por livros e cursos.

class Pilha {
  constructor() {
    this._top = null;
    this._count = 0;
  }

  //Continuação do código

Como você pode ver, teremos apenas duas variáveis de controle, _top que fará referencia para o topo da pilha e _count que controlará quantos itens a pilha possuí.

 

GetCount()

O método GetCount é o mais simples de todos. Ele apenas irá retornar a quantidade de itens na pilha.

GetCount = function () {
  return this._count;
};

 

Peek()

Exibe o item no topo da pilha ou null caso ela esteja vazia.

Peek = function () {
  if (this._top) {
    return this._top.data;
  }
  return null;
};

 

Push(item)

O método Push (empurrar) é a forma como adicionaremos itens a pilha. Pelo fato de ser uma linguagem não tipada, poderemos adicionar qualquer valor a pilha que ela o aceitará.

Push = function (data) {
  let node = {
    data: data,
    next: null
  };
  node.next = this._top;
  this._top = node;
  this._count++;
};

Como você pode ver, o método cria um objeto chamado node (nó) que é um objeto JS e terá 2 propriedades, o data (dados em inglês) para o valor e next (próximo) para referência o item anterior. Após isso definimos este novo valor como sendo o do topo e referenciamos o antigo topo no next.

Isto é feito desta forma pois para a pilha, é importante termos um controle de quem está no topo. Os outros itens serão manipulados apenas quando chegar a vez deles.

 

Pop()

O Método Pop (tirar) funciona da forma oposta ao Push, ele remove o item que está no topo da fila.

Pop = function () {
  if (this._top) {
    let out = this._top;
    this._top = this._top.next;
    if (this._count > 0) {
      this._count--;
    }
    return out.data;
  }
  return null;
};

Como você pode ver o código acima faz o seguinte: Confere se existe algum item no topo da fila para poder remove-lo, transforma o next em topo, reduz a contagem em 1 e retorna o item removido ou null caso esteja vazio.

 

DisplayAll()

Este método exibe todos os itens da pilha, do topo ao fundo, no formato de um vetor JavaScript. Caso a pilha esteja vazia, retorna null

DisplayAll = function () {
  if (this._top) {
    let arr = new Array();
    let current = this._top;
    for (let i = 0; i < this._count; i++) {
      arr[i] = current.data;
      current = current.next;
    }
    return arr;
  }

  return null;
};

Apesar deste código ter um pouco mais de lógica que os métodos anteriores, ele ainda é fácil de entender. Ele testa se o _top não está vazio e se verdadeiro, percorrerá a pilha copiando o valor armazenado dentro de cada nó para dentro do vetor.


Executando o código

Após criar a classe, um teste simples ajudará a verificar que todos os métodos estão fazendo o que deveriam

let pilha = new Pilha();

console.log(`Contagem: ${pilha.GetCount()}`);

pilha.Push(4);
console.log(`Peek: ${pilha.Peek()}`);
console.log(`Contagem: ${pilha.GetCount()}`);

pilha.Push(22);

console.log(`Contagem: ${pilha.GetCount()}`);

console.log(`Pop: ${pilha.Pop()}`);
console.log(`Pop: ${pilha.Pop()}`);
console.log(`Pop: ${pilha.Pop()}`);

console.log(`Contagem: ${pilha.GetCount()}`);

pilha.Push(1);
pilha.Push(-2);
pilha.Push(100);
pilha.Push(350);

console.log(`Todos: ${pilha.DisplayAll()}`);

Cursos completos de JavaScript

Seguindo a linha da postagem feita ano passado sobre Cursos completos que você não conhecia, estou postando uma nova lista atualizada para de cursos de empresas menos conhecidas, mas que nem por isso sejam ruins. Já cursei alguns dos listados abaixo e posso dizer que são muito bons.

Para ficar mais fácil de se organizar, os cursos estão agrupados pelas pessoas ou empresas que os criaram.


Alfamidia

Programação JavaScript Completo

Descrição: Um curso do básico ao avançado sobre JavaScript e JQuery. Ele permite que um pessoa que não saiba muito de programação possa aprender a usar o JS e conceitos mais avançados de programação a medida que o aluno avança nas aulas

Nível: Básico – Avançado

Duração: Você define e o curso possuí acesso vitálicio

Curso recebe atualizações: Não

Investimento: Sob consulta

 

Desenvolvimento Web e Mobile

Descrição: O curso online de desenvolvimento web e mobile percorre todos os campos da programação (do front-end ao back-end). O intuito é ensinar o estudante a ser um desenvolvedor com capacitação em todas as áreas do desenvolvimento de apps.

Nível: Básico – Avançado

Duração: Você define e o curso possuí acesso vitálicio

Curso recebe atualizações: Não

Investimento: Sob consulta

 


A´gora

JavaScript Completo

Descrição: Completo e passo a passo tem por objetivo principal ensinar todos os passos necessários que um iniciante na linguagem javascript precisa para dominar esta linguagem de programação que está crescendo bastante neste últimos tempos. Nela você terá todos os conhecimentos exigidos pelo mercado, do mais elementar ao mais avançados.

Nível: Básico

Duração: Você define e o curso possuí acesso vitálicio

Curso recebe atualizações: Não

Investimento: R$197,00, podendo parcelar em 2x sem juros

 

Formação Jquery Completo

Descrição: Este curso tem por objetivo ensinar do básico ao avançado do Jquery. Então você não tem muito conhecimento ou gostaria de aprimorar o que sabe para o nível profissional, esse é o curso ára você.

Nível: Básico

Duração: Você define e o curso possuí acesso vitálicio

Curso recebe atualizações: Não

Investimento: R$157,00, podendo parcelar em 2x sem juros


Udacity

Fundamentos Web Front-End

Descrição: Curso criado nos Estados Unidos com o foco em ensinar os fundamentos da programação Front-end. Ele lida com diversos detalhes da programação JavaScript não encontramos em qualquer lugar e aponta você para outros cursos gratuitos dentro do site deles.

Nível: Básico

Duração: 2 meses de curso e acesso irrestrito somente se você completar tudo

Curso recebe atualizações: Não

Investimento: 5 x R$106,00 – Com desconto à vista

 

Web Front-end Avançado

Descrição: Continuação do curso anterior. Aprofunda-se no entendimento do JavaScript de forma a ensinar a diferença entre as novas técnicas e as antigas. Você também descobrirá mais sobre o ganho de performance e aumento de produtividade do ES6.

Nível: Avançado

Duração: 3 meses meses de curso e acesso irrestrito somente se você completar tudo

Curso recebe atualizações: Não

Investimento: 9 x R$119,00 – Com desconto à vista

 


Danki Code

Curso Webmaster Front-end Completo

Descrição: Um curso de front-end bem completo que tem por objetivo ensinar do zero sobre como lidar com todos aspectos da tela, tanto visuais quanto lógicas. Diferente de um curso de web design que foca mais na questão visual e manipulação de imagens

Nível: Do básico ao avançado

Duração: Você define seu ritmo e com acesso vitalício.

Curso recebe atualizações: Sim

Investimento: 12 x R$19,00 – Com desconto à vista

 

Pacote Fullstack

Descrição: Inclui o curso Webmaster Front-end completo mencionado acima e fornece ainda mais material para ensina-lo sobre o funcionamento do back-end. É bem indicado para aqueles que querem se tornar desenvolvedores responsaveis (ou com o conhecimento) de ambas pontas da criação de uma aplicação web.

Nível: Do básico ao avançado

Duração: Você define

Tempo de acesso: Irrestrito

Curso recebe atualizações: Sim

Investimento: 12 x R$27,00 – Com desconto à vista

 

Desenvolvimento Web Completo

Descrição: Pronto para além de estudar os conceitos de HTML, CSS e JavaScript, também estudar muito PHP? Se sim, esse curso tavez seja para você. No curso de desenvolvimento Web Completo você estará se tornando um desenvolvedor Full Stacke aprendendo a conectar todas as pontas de uma aplicação web.

Nível: Do básico ao avançado

Duração: Você define

Tempo de acesso: Irrestrito

Curso recebe atualizações: Sim

Investimento: 12 x R$22,12 – Com desconto à vista


 

Conclusão

Isso ai, espero que algum destes cursos possam ajudar alguém. Caso você tenha uma duvida, pegunta ou sugestão, deixe seu comentário aqui abaixo para que possamos melhorar essa postagem.