Separando um array de strings em conjuntos de arrays ordenados alfabeticamente com JavaScript

Separando um array de strings em conjuntos de arrays ordenados alfabeticamente com JavaScript

Neste artigo vamos ver como podemos ordenar um array em JavaScript e separar os resultados em arrays ordenados alfabeticamente. Nosso objetivo será quebrar um array e criar um array para cada letra, de acordo com o conteúdo do array original.

Nos exemplos que vamos ver neste artigo vamos trabalhar com o seguinte array:

 

var times = ["Palmeiras", "Flamengo", "Cruzeiro", "Internacional", "Fluminense", "Corinthians", "Athletico-PR","Atlético", "Fortaleza","São Paulo","América", "Botafogo", "Santos", "Goiás", "Red Bull Bragantino", "Coritiba", "Cuiabá", "Grêmio", "Vasco", "Bahia"];

 

O que vamos aprender neste artigo?

 

* Separando um array de strings utilizando Reduce

* Separando um array de strings utilizando Reduce e convertendo cada elemento num objeto

* Separando um array de strings utilizando Map

 

 

 Separando um array de strings utilizando Reduce

 

O método reduce é uma função iteradora que passa por todos os elementos de um array e executa uma regra para cada um desses elementos.  Reduce pode receber até quatro parâmetros, que são os seguintes:

 

1 - acumulador (acc) – valor inicial, ou o valor do callback anterior.

2 - valorAtual (cur) – o valor do elemento atual.

3 - index (idx) – o índice atual.

4 - array original (src)- o array onde a iteração está ocorrendo.

 

Vamos ver o código em ação e na sequência vamos explicar o seu funcionamento:

 

var times = ["Palmeiras", "Flamengo", "Cruzeiro", "Internacional", "Fluminense", "Corinthians", "Athletico-PR","Atlético", "Fortaleza","São Paulo","América", "Botafogo", "Santos", "Goiás", "Red Bull Bragantino", "Coritiba", "Cuiabá", "Grêmio", "Vasco", "Bahia"];

var resultados = times.reduce((acc, cur) => {

    // cur[0] é a primeira letra de cada item do array

    let k = cur[0].toLocaleUpperCase()

    // Adiciona numa entrada existente ou cria uma nova

    if (acc[k]) acc[k].push(cur)

    else acc[k] = [cur]

    return acc

}, {})

console.log(resultados);

 

Se você deseja ver apenas os times que começam com a letra "A", pode fazer da seguinte forma:

 

console.log(resultados["A"]);

 

E se dentro da lista de times com a letra "A" você quiser acessar o seguinte elemento basta fazer isso:

 

console.log(resultados["A"][1]);

 

Vamos entender como funcionou o reduce. Perceba que ele recebeu apenas dois parâmetros.

 

var resultados = times.reduce((acc, cur) => {

    // Codigo a ser executado

}, {})

 

Como vimos na explicação sobre o reduce, o primeiro parâmetro, que no nosso exemplo recebeu o nome de "acc" é o acumulador, que pode ser o valor inicial ou o valor do callback anterior. Já o segundo parâmetro, que noneamos como "cur", é o item atual que está sendo iterado.

 

var resultados = times.reduce((acc, cur) => {

    // cur[0] é a primeira letra de cada item do array

    let k = cur[0].toLocaleUpperCase()

// ... código a ser executado.

}, {})

 

Na sequência criamos uma variável chamada "k", com a primeira letra do item que está sendo iterado, para extrair a primeira letra fizemos cur[0]. Convertemos está letra em maísculo utilizando o metodo .toLocaleUpperCase(), mas no nosso caso isso não era necessário já que a primeira letra de cada item de nosso array já está em maiúsculo.

Para terminar, verificamos se no nosso parâmetro acumulador já existe uma entrada de array cuja chave seja a letra atual. Se existir, adiciona um novo elmento utilizando o método push, caso contrário cria um novo elemento no array. Como você deve ter percebido ao testar o código, para cada letra foi criado um array. Perceba que o resultado do nosso reduce foi o primeiro parâmetro, ou seja, o parâmetro acumulador que foi sendo criado/alterado a cada iteração com os itens do array.

 

var resultados = times.reduce((acc, cur) => {

    // cur[0] é a primeira letra de cada item do array

    let k = cur[0].toLocaleUpperCase()

    // Adiciona numa entrada existente ou cria uma nova

    if (acc[k]) acc[k].push(cur)

    else acc[k] = [cur]

    return acc

}, {})

 

Convertendo os resultados de cada letra num objeto

 

Neste exemplo nós também vamos usar o reduce, exatamente da mesma forma como no exemplo anterior. O que vai mudar é a forma como o resultado vai ser entregue. Cada entrada do array resultado vai receber um objeto contendo dois campos, o primeiro chamado letra e o segundo chamado data com um array contendo os nomes dos times que começam com aquela letra.

 

var times = ["Palmeiras", "Flamengo", "Cruzeiro", "Internacional", "Fluminense", "Corinthians", "Athletico-PR","Atlético", "Fortaleza","São Paulo","América", "Botafogo", "Santos", "Goiás", "Red Bull Bragantino", "Coritiba", "Cuiabá", "Grêmio", "Vasco", "Bahia"];

resultados = Object.values(

      times.reduce((acc, cur) => {

        let primeraLetra = cur[0].toLocaleUpperCase();

        if (!acc[primeraLetra]) {

          acc[primeraLetra] = { letra: primeraLetra, data: [cur] };

        } else {

          acc[primeraLetra].data.push(cur);

        }

        return acc;

      }, {})

    );

console.log(resultados);

 

O método estático Object.values() retorna um array de objetos.

Perceba que neste exemplo cada entrada do array é um objeto contendo dois elementos, o primeiro é a letra e o segundo é um array com os times que começam com aquela letra. Perceba que este array resultados está fora da ordem alfabética. Para resolver isso, podemos ordenar os resultados utilizando o método sort e passando para este método um parâmetro que será uma função que vai ordenar os resultados de acordo com o campo "letra":

 

var times = ["Palmeiras", "Flamengo", "Cruzeiro", "Internacional", "Fluminense", "Corinthians", "Athletico-PR","Atlético", "Fortaleza","São Paulo","América", "Botafogo", "Santos", "Goiás", "Red Bull Bragantino", "Coritiba", "Cuiabá", "Grêmio", "Vasco", "Bahia"];

resultados = Object.values(

      times.reduce((acc, cur) => {

        let primeraLetra = cur[0].toLocaleUpperCase();

        if (!acc[primeraLetra]) {

          acc[primeraLetra] = { letra: primeraLetra, data: [cur] };

        } else {

          acc[primeraLetra].data.push(cur);

        }

        return acc;

      }, {})

    );

function ordenar(a,b) {

if (a.letra < b.letra)

     return -1;

  if (a.letra > b.letra)

    return 1;

  return 0;

}

console.log(resultados.sort(ordenar));

 

Se você quiser acessar a entrada referente a letra "A" pode utiilizar o método find e filtrar pelo campo letra de cada item do array:

 

console.log(resultados.find((x) => x.letra === "A"));

 

Utilizando Map

 

Este vai ser um exemplo um pouco mais complexo, vamos utiilzar o objeto Map. O objeto Map guarda coleções de elementos chave-valor. No exemplo a seguir o conteúdo da variável resultados é criada atrávés de uma arrow function. As arrow function existem desde a versão ES6 do ECMAScript.

 

var times = ["Palmeiras", "Flamengo", "Cruzeiro", "Internacional", "Fluminense", "Corinthians", "Athletico-PR","Atlético", "Fortaleza","São Paulo","América", "Botafogo", "Santos", "Goiás", "Red Bull Bragantino", "Coritiba", "Cuiabá", "Grêmio", "Vasco", "Bahia"];

let resultados = ((m, a) => (a.forEach(s => {

  let a = m.get(s[0].toLocaleUpperCase()) || [];

  m.set(s[0].toLocaleUpperCase(), (a.push(s), a));

}), m))(new Map(), times);

console.log(resultados.get("A"));

 

Para acessar o primeiro elemento que começa com a letra "A":

 

console.log(resultados.get("A")[1]);

 

Vamos entender como funcionou a ordenação utilizando o objeto Map. Perceba que fizemos a iteração dos itens do array utilizando forEach.

 

let resultados = ((m, a) => (a.forEach(s => {

  //Codigo a ser executado

}), m))(new Map(), times);

 

Antes do nosso forEach existem dois parâmetros, o "m" e o "a". O primeiro parâmetro é o acumulador, ele recebe um novo objeto Map que vai ser criado, já o segundo parâmetro são os dados, que no nosso caso é o array de times.

A primeira instrução que executamos foi verificar se existe em nosso objeto Map um elemento com uma chave igual a letra atual. Para retornamos um elemento do Map de acordo com uma chave utilizamos o método GET. Neste exemplo a variável A pode ser o conteudo da chave com a letra atual, ou um array vazio caso não tenha sido localizado.

 

let resultados = ((m, a) => (a.forEach(s => {

  let a = m.get(s[0].toLocaleUpperCase()) || [];

  //Resto do código

}), m))(new Map(), times);

 

Por fim precisamos atualizar a chave ou criar caso não exista. Para adicionar novos elementos ao objeto Map utilizamos o método SET. O método SET recebe dois parâmetros, o primeiro é o nome da chave, que em nosso caso é uma letra, o segundo parâmetro é o conteúdo desta chave, que será o array com os nomes dos times que começam com a mesma letra da chave atual. Da mesma forma que fizemos nos exemplos anteriores, depois de recuperar o array da letra atual fazemos um push para adicionar o novo elemento.

 

let resultados = ((m, a) => (a.forEach(s => {

  let a = m.get(s[0].toLocaleUpperCase()) || [];

  m.set(s[0].toLocaleUpperCase(), (a.push(s), a));

}), m))(new Map(), times);

 

Além dos métodos GET e SET, temos o método HAS para verificar se existe uma determinada chave, ele retorna TRUE em caso de sucesso e FALSE se não localizar a chave informada.

 

console.log(resultados.has("X"));

 

E para excluir uma chave você pode utilizar o método DELETE. 

 

console.log(resultados.size);

resultados.delete("C");

console.log(resultados.size);

 

No exemplo anterior utilizamos o método SIZE para verificar a quantidade de elementos de nosso objeto Map.

 

Para apagar todo o conteúdo de um objeto Map podemos usar o método CLEAR()

 

resultados.clear();

 

Está começando e deseja saber o que precisa estudar de HTML e JavaScript? Não deixe de conferir os roteiros de estudo de HTML e JavaScript!. São dezenas de conteúdos para você melhorar suas habilidades.

Roteiro de estudos - HTML e CSS

Roteiro de estudos - Javascript

 

Outros conteudos que podem ser de seu interesse

Percorrer as propriedades de um objeto com JavaScript
25/11/2019JAVASCRIPT

Percorrer as propriedades de um objeto com JavaScript

Veja as várias formas de fazer loop nas propriedades de um objeto

Saiba mais...
Remover elementos de um array com JavaScript
16/08/2020JAVASCRIPT

Remover elementos de um array com JavaScript

Confira as várias formas de apagar elementos de uma array com JavaScript

Saiba mais...

Conteúdo sobre banco de dados sem complicação!