15
respostas

criação de API oom express

Alguém poderia me ajudar com esse trabalho, tenho que fazer ele para amanha, e estou perdido, não sei como importar os arquivos, não sei como começar.

Enunciado

O aluno deverá criar um projeto Node.js para realizar a criação de alguns métodos e processamento de arquivos JSON.

Atividades

O aluno deverá baixar os arquivos Cidades.json e Estados.json do link a seguir (https://github.com/felipefdl/cidades-estados-brasil-json (Links para um site externo.)) e colocá-los dentro do seu projeto. O arquivo Estados.json possui uma listagem com todos os estados do Brasil, cada um representado por um ID. No arquivo Cidades.json estão listadas todas as cidades do Brasil, com seu respectivo estado representando pelo ID fazendo referência ao arquivo Estados.json.

O aluno deverá desempenhar as seguintes atividades:

  • Implementar um método que irá criar um arquivo JSON para cada estado representado no arquivo Estados.json, e o seu conteúdo será um array das cidades pertencentes aquele estado, de acordo com o arquivo Cidades.json. O nome do arquivo deve ser o UF do estado, por exemplo: MG.json.

  • Criar um método que recebe como parâmetro o UF do estado, realize a leitura do arquivo JSON correspondente e retorne a quantidade de cidades daquele estado.

  • Criar um método que imprima no console um array com o UF dos cinco estados que mais possuem cidades, seguidos da quantidade, em ordem decrescente. Utilize o método criado no tópico anterior. Exemplo de impressão: [“UF - 93”, “UF - 82”, “UF - 74”, “UF - 72”, “UF - 65”]

  • Criar um método que imprima no console um array com o UF dos cinco estados que menos possuem cidades, seguidos da quantidade, em ordem decrescente. Utilize o método criado no tópico anterior. Exemplo de impressão: [“UF - 30”, “UF - 27”, “UF - 25”, “UF - 23”, “UF - 21”]

  • Criar um método que imprima no console um array com a cidade de maior nome de cada estado, seguida de seu UF. Em caso de empate, considerar a ordem alfabética para ordená-los e então retornar o primeiro. Por exemplo: [“Nome da Cidade – UF”, “Nome da Cidade – UF”, ...].

  • Criar um método que imprima no console um array com a cidade de menor nome de cada estado, seguida de seu UF. Em caso de empate, considerar a ordem alfabética para ordená-los e então retorne o primeiro. Por exemplo: [“Nome da Cidade – UF”, “Nome da Cidade – UF”, ...].

  • Criar um método que imprima no console a cidade de maior nome entre todos os estados, seguido do seu UF. Em caso de empate, considerar a ordem alfabética para ordená-los e então retornar o primeiro. Exemplo: “Nome da Cidade - UF".

  • Criar um método que imprima no console a cidade de menor nome entre todos os estados, seguido do seu UF. Em caso de empate, considerar a ordem alfabética para ordená-los e então retornar o primeiro. Exemplo: “Nome da Cidade - UF".

  • O projeto ao ser executado, deve realizar os cinco métodos em sequência, imprimindo os resultados em console e depois finalizando a execução.

15 respostas

Olá Daniel, tudo bem com você?

Realmente são bastantes coisas para fazer e para isso são necessárias varias funções:

  1. Ler e Escrever Arquivos

Para isso temos a biblioteca fs do próprio node que podemos utilizar 2 funções: readFileSync e writeFileSync:

Veja que por conta de facilidade irei criar uma série de funções utilizando arrow functions

const fs = require('fs');

const readFile = (filename) => fs.readFileSync(filename, "UTF-8");
const saveFile = (filename, content) => fs.writeFileSync(filename, content, "UTF-8")
const jsonToObject = (string) => JSON.parse(string);

Para ler os arquivos agora é bem simples:

const estados = jsonToObject(readFile("Estados.json"));
const cidades = jsonToObject(readFile("Cidades.json"));

Veja que eu estou lendo e transformando o arquivo em um objeto javascript :)

Basicamente irei trabalhar agora com map, filter e sort

Parte 1: Jsons

const filterCityByState = (stateId, cities) => cities.filter(city => city.Estado === stateId);

Essa é apenas uma função que dado o id de um estado procura no array de cidades a com o mesmo id

Irei utilizar isso para criar os arquivos:

function statesToJSON(states, cities) {
    states.forEach(state => {
        const citiesOfState = filterCityByState(state.ID, cities);
        saveFile(`${state.Sigla}.json`, JSON.stringify(citiesOfState, null, 4));
    });
}

Veja que eu estou utilizando a função de salvar que recebe o nome da sigla do Estado e o conteúdo é a string dos arrays filtrados, e eu faço isso para cada estado :) Ao executar essa função será criado vários arquivos JSONS no formato esperado

Parte 2: Quantidade

Bem essa função será bem simples, precisamos ler o arquivo e pegar apenas a quantidade:

const stateNumberOfCities = (uf) => jsonToObject(readFile(`${uf}.json`)).length;

Agora eu vou colocar várias funções de ordenação, que você pode conhecer aqui:

const descCriteriaForNumbers = (a, b) => b.count - a.count;
const ascCriteriaForNumbers = (a, b) => a.count - b.count;

Onde temos asc para ordenar valores de maneira crescente, e desc para decrescente para valors numéricos

Agora que já temos isso é bem fácil:

function filterStatesByNumbeOfCities(states, criteria) {

    const arrayWithNumberOfCities = states.map(state => ({ ...state, count: stateNumberOfCities(state.Sigla) }))
    const sortedArray = arrayWithNumberOfCities.sort(criteria);

    const result = sortedArray.slice(0, 5).map(state => `${state.Sigla} - ${state.count}`);

    return result;

}
const top5EstadosComMaioresCidades = filterStatesByNumbeOfCities(estados, descCriteriaForNumbers);
const top5EstadosComMenoresCidades = filterStatesByNumbeOfCities(estados, ascCriteriaForNumbers).reverse();

E dessa maneira já temos o resultado esperado :)

[ 'MG - 853', 'SP - 645', 'RS - 496', 'BA - 417', 'PR - 399' ]
[ 'RO - 52', 'AC - 22', 'AP - 16', 'RR - 15', 'DF - 1' ]

Para fazer a filtragem das cidades por número de letras teremos o mesmo comportamento, irei definir duas funções de comparação baseadas no tamanho da palavra:

const ascCriteriaForLenght = (a, b) => {
    if( a.Nome.length < b.Nome.length) return -1;
    if ( a.Nome.length > b.Nome.length) return 1;
    if ( a.Nome.length == b.Nome.length) return a.Nome.localeCompare(b.Nome)
}

const descCriteriaForLength = (a, b) => { 
    if( a.Nome.length < b.Nome.length) return 1;
    if ( a.Nome.length > b.Nome.length) return -1;
    if ( a.Nome.length == b.Nome.length) return a.Nome.localeCompare(b.Nome)
};

Agora vamos para a função:

function filterCityFromStateByLength(states, criteria) {

    const result = [];

    states.forEach(state => {
        const biggerCityName = jsonToObject(readFile(`${state.Sigla}.json`)).sort(criteria)[0];
        result.push(`${biggerCityName.Nome} - ${state.Sigla}`)
    })

    return result;
}

Estou apenas lendo os arquivos JSONS de cada estado e ordedando pelo critério que queremos :)

Dessa maneira para ter o resultado precisamos apenas:

const menoresCidadesDeCadaEstado = filterCityFromStateByLength(estados, ascCriteriaForLenght);
const maioresCidadesDeCadaEstado = filterCityFromStateByLength(estados, descCriteriaForLength)

E a última parte que são as menores de cada cidade é apenas fazer novamente uma comparação

function filterTheMostCityFromAllStates(states, cities, criteria) {
    const nameOfCity = cities.map(city => ({ Nome: city.Nome, uf: city.Estado})).sort(criteria)[0];
    const UFOfCity = states.filter( state => state.ID === nameOfCity.uf)[0];

    return `${nameOfCity.Nome} - ${UFOfCity.Nome}`

}

Como são varias funções criei uma função main para executar todas em sequência:

(function main(){

    const states = jsonToObject(readFile("Estados.json"));
    const cities = jsonToObject(readFile("Cidades.json"));

    // Criar os 27 Json's
    statesToJSON(states, cities);

    // Devolve a quantidade de cidades de um estado pela UF

    const numberOfCitiesOfMG = stateNumberOfCities("MG");
    console.log(numberOfCitiesOfMG);

    //Filtrar os Top 5

    const topFiveStatesByAscNumberOfCities = filterStatesByNumbeOfCities(states, ascCriteriaForNumbers).reverse();
    console.log(topFiveStatesByAscNumberOfCities);
    const topFiveStatesByDescNumberOfCities = filterStatesByNumbeOfCities(states, descCriteriaForNumbers);
    console.log(topFiveStatesByDescNumberOfCities);

    // Filtrar o Top 5 por Letra

    const topCitiesByAscLenght = filterCityFromStateByLength(states, ascCriteriaForLenght);
    console.log(topCitiesByAscLenght);
    const topCitiesByDescLength = filterCityFromStateByLength(states, descCriteriaForLength);
    console.log(topCitiesByDescLength)

    // Filtrar as Maiores
    const biggestCity = filterTheMostCityFromAllStates(states, cities, ascCriteriaForLenght);
    console.log(biggestCity);
    const smallestCity = filterTheMostCityFromAllStates(states, cities, descCriteriaForLength); 
    console.log(smallestCity)

})();

Aqui o arquivo final

Abraços e Bons Estudos :)

Obrigado Geovani , você sempre me ajudando, ainda não deu tempo mas tenho que comentar nas outras ajudas que me deu, obrigado mesmo.

Esse projeto é de um curso que está tendo como matéria Node.Js, estão ensinando construir API, porem me perdi na matéria não entendi nada, andei pesquisando e vi que esse assunto já é avançado, minha duvida é essa, realmente tenho que começar do básico de Node, ou não consigo entender sobre API sem nunca ter visto nada.

Obrigado.

Eu consigo fazer esse comando aqui, ou algo parecido para ir acompanhando o resultado no Insomnia.

app.get('/', function(req, res){

    res.send(console.log(estados));
})

Eu não entendi como essa função acessa o array estados e cidades.

const filterCityByState = (stateId, cities) => cities.filter(city => city.Estado === stateId);

Tudo bem Geovani, eu tentei até agora entender seu código, mas realmente eu estou com essa dificuldade enorme de entender o código e essa parte de node.js, saberia me indicar quais cursos tenho que fazer para entender esse código e começar a programar desse jeito.

Estou sem entender:

  • as funções
  • como juntar os dois arrays
  • como faz leitura de algo e faz a comparação
  • como faz a ordenação
  • como ler o tamanho de caracteres no array
  • entre outras coisas.

Não é só neste trabalho que estou co dificuldades, andei postando outros que você me ajudou.

Se puder me indicar livro, vídeo, tutorial e curso, me ajudaria muito. por que já estou quase desistindo de programar.

Obrigado.

Olá Daniel, bom dia :)

Se puder me indicar livro, vídeo, tutorial e curso, me ajudaria muito. por que já estou quase desistindo de programar.

Não pode desistir não! Acredito que você apenas foi parar em um curso que requer conhecimento que você ainda não tem, e ai ficamos perdidos mesmo, eu realmente acho que é um conteúdo médio / avançado com javascript e requer uma boa bagagem, então a questão é justamente aprender com calma. respeitando o seu tempo de aprendizagem, criar API com Express é extremamente divertido, mas precisamos saber bem o javascript para isso, caso contrário estamos apenas pulando etapa, é como saber boiar e querer nadar em alto mar :)

Agora indo pelas perguntas na ordem que foi feita:

app.get('/', function(req, res){

    res.send(console.log(estados));
})

Iremos utilizar o console.log apenas para imprimir informações em nosso terminal, quando queremos enviar dados para o cliente (em formato json nesse caso), precisamos utilizar o seguinte formato:

res.json(estados)

Ou seja, devolva como resposta, em formato json, o conteúdo que está armazenado na variável estado

Eu não entendi como essa função acessa o array estados e cidades.

const filterCityByState = (stateId, cities) => cities.filter(city => city.Estado === stateId);
`

Vamos por partes, pegando a função inteira:

    states.forEach(state => {
        const citiesOfState = filterCityByState(state.ID, cities);
        saveFile(`${state.Sigla}.json`, JSON.stringify(citiesOfState, null, 4));
    });

Então começamos com o states.forEach, ou seja, vamos iterar sobre o array de estados, e para cada estado, eu estou chamando a função filterCityByState passando o id do estado e o array de cidades, então vamos supor da seguinte maneira:

estados = [ 
{ "ID": 1, "Sigla": "AC", "Nome": "Acre"},
{ "ID": 26, "Sigla": "SP", "Nome": "São Paulo"}
]

cidades = [
{ "ID": 79, "Nome": "Acrelândia", "Estado": 1 },
{ "ID": "285", "Nome": "Agua Fria", "Estado"; 5 },
{ "ID": "4826", "Nome": "Caraguatatuba", "Estado" : 26}
{ "ID": 5270, "Nome": "São Paulo", "Estado": 26}
{ "ID":  5329, "Nome": "Ubatuba", "Estado": 26}
]
`

Então como vamos iterar por estados, o primeiro vai ser:

state = { "ID": 1, "Sigla": "AC", "Nome": "Acre"},

Então chamamos a função filterCityByState( 1, cidades)

Agora o que estados e cidades tem em comum ? O ID do Estado é o campo Estado em cidades, e aqui temos a função:

const filterCityByState = (stateId, cities) => cities.filter(city => city.Estado === stateId);

Então temos que:

stateId = 1
cities = Aquele array enorme

E aqui precisamos antes entender um pouco sobre o filter, o que ele faz na verdade é devolver um novo array com os elementos que passaram no teste, no caso o nosso teste é que o valor do campo Estado para cidade seja igual ao ID que passamos para a função

Eu vou fazer cities.filter, isto é, vou iterar em cada elemento do meu array de cidades e para cada cidade fazer uma comparação:

Primeira iteração:

cidade: { "ID": 79, "Nome": "Acrelândia", "Estado": 1 },

stateId = 1
cidade.Estado = 1

Opa, é verdadeiro então esse elemento automaticamente está no array que a função filter devolve, vamos para a segunda iteração:

{ "ID": "285", "Nome": "Agua Fria", "Estado"; 5 },

stateId = 1
cidade.Estado = 5

Como é falso, não entra no array de resposta, e vamos para a próxima iteração, e dessa forma depois de percorrer todos elementos do array de cidades eu terei uma lista apenas com os elementos que tem o cidade.Estadoigual ao Id passado :)

Então o resultado dessa função foi:

cidadesDoEstado = [ 
{ "ID": 79, "Nome": "Acrelândia", "Estado": 1 }, 
]

Iremos salvar:

 saveFile(`${state.Sigla}.json`, JSON.stringify(citiesOfState, null, 4));

Veja que state.Sigla nada mais é do que "AC", e o conteúdo a ser salvo é o texto contido em cidadesDoEstado

Iremos agora voltar para a função:

    states.forEach(state => {
        const citiesOfState = filterCityByState(state.ID, cities);
        saveFile(`${state.Sigla}.json`, JSON.stringify(citiesOfState, null, 4));
    });
estados = [ 
{ "ID": 1, "Sigla": "AC", "Nome": "Acre"}, --> Acabamos de terminar
{ "ID": 26, "Sigla": "SP", "Nome": "São Paulo"}
]

Temos novamente o mesmo processo:

state = { "ID": 26, "Sigla": "SP", "Nome": "São Paulo"}

Chamamos a função:

filterCityByState( state.ID, cidades)
filterCityByState( 26, cidades)

E dentro da função teremos:

stateId = 26
cities = Aquele array enorme

Primeira iteração:

cidade: { "ID": 79, "Nome": "Acrelândia", "Estado": 1 },

stateId = 26
cidade.Estado = 1

Dessa vez é falso, então não estará presente no array final :)

{ "ID": "285", "Nome": "Agua Fria", "Estado"; 5 },

stateId = 26
cidade.Estado = 5

Aqui também temos que é falso!

{ "ID": "4826", "Nome": "Caraguatatuba", "Estado" : 26}

stateId = 26
cidade.Estado = 26

Verdadeiro, então estará no nosso array

{ "ID": 5270, "Nome": "São Paulo", "Estado": 26}

stateId = 26
cidade.Estado = 26

Verdadeiro também :)

E assim sucessivamente, dessa forma ao terminar de percorrer todos elementos de cidade vamos novamente salvar:

cidadesDoEstado = [
{ "ID": "4826", "Nome": "Caraguatatuba", "Estado" : 26},
{ "ID": 5270, "Nome": "São Paulo", "Estado": 26}
]
 saveFile(`${state.Sigla}.json`, JSON.stringify(citiesOfState, null, 4));

Sabemos que o state atual é o:

state = { "ID": 26, "Sigla": "SP", "Nome": "São Paulo"}

E o conteúdo a ser salvo é o texto presente em cidadesDoEstado, dessa forma percorremos todos os estados do nosso exemplo e a função é encerrada :)

Agora vamos para as dúvidas gerais, sobre o que você não está conseguindo entender:

  • as funções

Aqui vai ser um pouco mais complicado de entender, esse exercícios que você passou trabalham com uma ideia mais avançada de javascript, para o final da sua dúvida irei te recomendar algumas coisas, mas logo de cara algo que eu recomendaria seria ver esse video que trabalha essa parte de filtragem com javascript :)

  • como juntar os dois arrays

Opa, isso deu para entender na parte de cima, não iremos em nenhum momento juntar os dois arrays, iremos pegar a informação que eles tem em comum, o campo ID e o campo Estado e trabalhar com a filtragem

  • como faz leitura de algo e faz a comparação

A leitura é bem simples:

Importamos o fs

const fs = require('fs');

Para ler um arquivo precisamos utilizar a função fs.readFileSync( nomeDoArquivo, codificação, em nosso caso temos 2 arquivos a serem lidos no começo: "Estados.json" e "Cidades.json"

Então fazemos:

fs.readFileSync( "Estados.json", "UTF-8") 

Isso nos devolverá o conteudo do arquivo em formato String, entretanto para trabalhar com o javascript precisamos que esse conteúdo esteja em um formato de objeto, para isso temos uma função chamada JSON.parse, que faz essa conversão de string para objeto

Veja que quando eu fui salvar eu fiz JSON.stringify, que é a função inversa, ela pega um objeto javascript e transforma em uma string para que eu possa salvar em um arquivo de texto :)

Já entrando nesse assunto para salvar é a mesma coisa:

fs.writeFileSync( nomeDoArquivo, conteudoASerSalvo, codificacao)

Em nosso caso era sempre a mesma coisa:

fs.writeFileSync( nomeDoArquivo, conteudoASerSalvo, codificacao)
fs.wirteFileSync( `${state.Sigla}`, conteudoDoArray, "UTF-8"
  • como faz a ordenação

Para ordenar um array temos o método sort, que recebe como parâmetro uma função de ordenação, essa função de ordenação sempre tem 2 parâmetros que é o elemento A e o elemento B, por exemplo:

function ordenarNumeros( a, b ) {
    if( a > b ) return 1
    if( a < b) return -1
    if ( a == b) return 0
}

Agora vamos ter esse array como base:

const array = [8, 10, 15, 3, 80, 1, 7]

Se fizermos array.sort(ordernarNumeros), teremos:

arr.sort(ordenarNumeros)
Array(7) [ 1, 3, 7, 8, 10, 15, 80 ]

Isso porque, a função de comparação pode retonar 3 valores, se A for menor que B, teremos um valor negativo, que significa para a função sort que o elemento Avem primeiro Se Afor maior que B teremos um valor positivo, que significa que B vem primeiro Se forem iguais ele simplesmente tenta manter a ordem

Ex:

pequenoArray = [ 2, 5, 3, 1]

Compara 2 com 5, vê que da negativo, então 2 vem primeiro
Compara 5 com 2, vê que da positivo, então 2 vem primeiro
Compara 5 com 3, vê que da positivo, então 3 vem primeiro
Compara 5 com 1, vê que da positivo, então 1 vem primeiro
[2, 3, 1, 5]
Compara 1 com 2, vê que da negativo, então 1 vem primeiro
[1, 2, 3, 5]
  • como ler o tamanho de caracteres no array

Não vamos ler a quantidade de caracteres de um array, normalmente escolheremos um campo que tem uma String para fazer a comparação entre elas, por exemplo:

        const biggerCityName = jsonToObject(readFile(`${state.Sigla}.json`)).sort(criteria)[0];

Aqui eu estou lendo o arquivo que tem a sigla de um estado, ex "SP.json" e transformando ele em um objeto ( que no caso vai ser um array) e pedindo para ordernar esse array de acordo com o critério, no caso:

const ascCriteriaForLenght = (a, b) => {
    if( a.Nome.length < b.Nome.length) return -1;
    if ( a.Nome.length > b.Nome.length) return 1;
    if ( a.Nome.length == b.Nome.length) return a.Nome.localeCompare(b.Nome)
}

Veja que para cidade dentro do Array eu irei faze a comparação com base no a.Nome que na verdade é uma String e dela eu pego a quantidade de letras com o .length, dessa maneira eu comparo os números :)

Agora de maneira mais geral em relação a suas dúvidas e recomendações :)

Esse assunto é um pouco complexo, não é simples pegar esse conteúdo em 1 semana, ou lendo as mensagens, é questão de alguns meses para que essa parte de filtragem, ordenação e mapear elementos se tornem algo natural, e para isso é necessário praticar e indo com calma, então:

O ideal seria fazer os cursos de base do Javascript

Esse cursos estão mais voltados para a parte de Frontend, entretanto dão uma boa base de javascript: arrow functions, foreach, map

O curso principal para fazer essa parte de filtragem seria esse:

Esse vídeo eu recomendei em mensagens anteriores mas vou recomendar novamente

Já te dará uma boa base dessa parte, e pode te ajudar a ir para o curso de Abordagem mais Funcional :)

E a partir disso podemos ir para a parte de API com Express e ai temos dentro da formação Node vários cursos:

Mas o principal é entender que é necessário ir estudando com calma, leva tempo para que você consiga fazer esse tipo de filtragem com facilidade, no começo é bater a cabeça e ter dificuldades, é normal, programação é algo fantástico mas que as vezes nos da um certo trabalho para aprender, o aprendizado é sempre uma coisa dura, mas vale muito a pena no final, o que não podemos fazer é pular etapas :)

Eu demorei bastante tempo para conseguir fazer essas coisas, e ainda tenho muito a melhorar, mas para isso é estudar constantemente e quebrando a cabeça :)

Abraços e Bons Estudos!

Obrigado Geovani, value pelas dicas.

Se não for pedir muito, teria como me explicar alguns pontos desse outro trabalho que o professor fez na aula ao vivo e fiquei perdido.

O trabalho era pegar o array de todas as rodadas dos times do Brasileirão 2003, e mostrar o campão com mais pontos.

Ele pegou desta pagina o array: https://github.com/geovannyAvelar/Dados-Abertos-Campeonato-Brasileiro

  • arquivo index.js
import express from "express";
import { promises } from "fs";
import timesRouter from "./routes/times.js";
const { readFile, writeFile } = promises;

const times = [];

//criando instancia do express
const app = express();

//definindo express para usar json
app.use(express.json());

//criando roteador /times para redirecionar requisicoes
app.use("/times", timesRouter);

//iniciando servidor
app.listen(3000, () => {
    console.log("API Started");
});

init();

async function init() {
    try {
        const resp = await readFile("./2003.json");        
        const data = JSON.parse(resp);

        //montando array de times
        data[0].partidas.forEach(partida => {
            times.push({ time: partida.mandante, pontuacao: 0 });
            times.push({ time: partida.visitante, pontuacao: 0 });
            console.log(times);
        });

insira seu código aqui

 //preenchendo pontuacao dos times no array
        data.forEach(rodada => {
            rodada.partidas.forEach(partida => {
                const indexVisitante = times.findIndex(item => item.time === partida.visitante);                    
                const indexMandante = times.findIndex(item => item.time === partida.mandante); 
                console.log(indexMandante);                                   

                let timeVisitante = times[indexVisitante];
                //console.log(times[indexVisitante]);
                let timeMandante = times[indexMandante];

                if (partida.placar_visitante > partida.placar_mandante) {                                        
                    timeVisitante.pontuacao += 3;
                    times[indexVisitante] = timeVisitante;
                } else if (partida.placar_mandante > partida.placar_visitante) {                                    
                    timeMandante.pontuacao += 3;
                    times[indexMandante] = timeMandante;                    
                } else {
                    timeVisitante.pontuacao += 1;
                    timeMandante.pontuacao += 1;
                    times[indexVisitante] = timeVisitante;                                        
                    times[indexMandante] = timeMandante;                    
                }
            });
        });

        //ordenar times de acordo com a pontuacao
        times.sort((a, b) => {
            return b.pontuacao - a.pontuacao;

        });

        //console.log(times)
        await writeFile("times.json", JSON.stringify(times));

    } catch (err) {
        console.log(err);
    }
}
  • arquivo times.js - ele fez uma rota aqui pelo que entendi
import express from "express";
import { promises } from "fs";

//criando roteador
const router = express.Router();
const { readFile } = promises;

//rota para responder get no /times/campeao
router.get("/campeao", async (req, res) => {
    res.send(await retornaCampeao());
});

async function retornaCampeao() {
    const resp = await readFile("times.json");
    const data = JSON.parse(resp);
    return data[0];
}

export default router;

vou colocar aqui as partes que eu não entendi:

   data[0].partidas.forEach(partida => {
            times.push({ time: partida.mandante, pontuacao: 0 });
            times.push({ time: partida.visitante, pontuacao: 0 });
            console.log(times);
        });

Aqui ele coloca os times dentro do array, que ele criou, só que quando dou um console.log aparece o mesmo time varias vezes:

  • por que acontece isso ?
  • não era para aparecer os 24 times só que tem no campeonato sem repetir ?
 //preenchendo pontuacao dos times no array
        data.forEach(rodada => {
            rodada.partidas.forEach(partida => {
                const indexVisitante = times.findIndex(item => item.time === partida.visitante);                    
                const indexMandante = times.findIndex(item => item.time === partida.mandante); 
                console.log(indexMandante);                                   

Aqui eu também dei um console.log e ele mostra um monte de números:

  • por que aparece esses números ?
  • não entendi a logica item.time === partida.visitante e item.time === partida.mandante? . Qual a logica dessa comparação, tentei entender mas ate agora não consegui.

Olá Daniel, tudo bem com você?

Vamos por partes :)

Aqui ele coloca os times dentro do array, que ele criou, só que quando dou um console.log aparece o mesmo time varias vezes:

A questão foi de onde você colocou o console.log, veja que está acontecendo um forEach, então a cada partida que está dentro de data[0].partidas] teremos a execução de um console.log, no caso 12 vezes ele irá fazer esse print, aqui temos 2 alternativas:

1) Colocar o console.log no lugar correto

Se queremos apenas um print com todos os times na verdade teriamos que colcoar esse console.log após a execução do forEach:

   data[0].partidas.forEach(partida => {
            times.push({ time: partida.mandante, pontuacao: 0 });
            times.push({ time: partida.visitante, pontuacao: 0 });
        });
console.log(times);

2) Pensar o que queremos imprimir

Na segunda maneira a gente não consegue entender o que acontece em cada iteração, para entender melhor a gente poderia criar um print com os elementos que estão sendo trabalhado, no caso:

   data[0].partidas.forEach(partida => {
            times.push({ time: partida.mandante, pontuacao: 0 });
            times.push({ time: partida.visitante, pontuacao: 0 });
  console.log(`Mandante: ${partida.mandante}  x  Visitante: ${partida.visitante}`)
        });

Agora em relação a sua segunda pergunta:

por que aparece esses números ?

Isso acontece porque está sendo utilizado o método findIndex e o que ele devolve na verdade é a posição que um elemento está no array, então por exemplo:

let times = [ "Corinthians", "Santos", "São Paulo", "Palmeiras"]

times.findIndex( time => time == "São Paulo")

>> 2

Como podemos ver a resposta foi 2, que é a posição onde está o nome Sâo Paulo ( lembre que a primeira posição de um array é 0 )

não entendi a logica item.time === partida.visitante e item.time === partida.mandante?

O que está sendo feito é que o nosso array times é da seguinte maneira:

[
  { time: 'Guarani', pontuacao: 0 },
  { time: 'São paulo', pontuacao: 0 },
  { time: 'São paulo', pontuacao: 0 },
]

E o elemento partida é da seguinte maneira:

   visitante: 'Vasco',
  resultado: 'vitoria_mandante',
  data_partida: '29/03/2003',
  placar_visitante: 2,
  hora_partida: '16h00',
  mandante: 'Guarani',
  placar_mandante: 4,
  estadio: 'Brinco de Ouro'

Agora observando novamente: times.findIndex(item => item.time === partida.visitante);

O que iremos é percorrer a nossa tabela de times, no caso podemos ver que item.time na verdade é o nome da equipe, até encontrar a posição no array onde item.time é igual a partida.visitante, ou seja, em que posição do nosso array está o time Vasco :)

A mesma coisa acontece para o caso do visitante, estamos apenas procurando o índice do array onde tem aquele nome :)

Vamos supor que encontramos na posição 8 do array, por isso que depois é feito:

let timeVisitante = times[indexVisitante];
timeVisitante = times[8]

Ou seja o time visitante equivale ao time na posição 8 do nosso array :)

Abraços!

Tudo bem Geovani , eu estava mexendo nesse código agora, e ainda continuo perdido aqui:

 data.forEach(rodada => {
            rodada.partidas.forEach(partida => {

                if (partida.placar_visitante > partida.placar_mandante) {   

                    const indexVisitante = times.findIndex(item => item.time === partida.visitante); 

                    let timeVisitante = times[indexVisitante];

                    timeVisitante.pontos += 3;
                    times[indexVisitante] = timeVisitante;
                }

            })

Vamos supor que indexVisitante seja 8 e o time seja "são paulo". Eu fiz por partes a logica como escrevi abaixo e não consegui entender ainda ela, como ela faz o incremento e adiciona no array, pela logica que fui fazendo por partes, o times[index] recebe o nome do time, eu exemplifiquei abaixo como fiz:

  • let timeVisitante = vai receber "são paulo"
  • timeVisitante.pontos += 3; = recebe são paulo.pontos + 3
  • times[indexVisitante] = timeVisitante; = recebe times[8] = são paulo

Outra duvida:

  • temos 4 linhas dentro do laço if, na linha 2 e 4 temos:

2 - let timeVisitante = times[indexVisitante];

4 - times[indexVisitante] = timeVisitante;

PORQUE: Ele faz timeVisitante = times[indexVisitante] e depois ao contrario times[indexVisitante] = timeVisitante, me perdi nessa logica.

Eu não entendi ainda essa logica, tem alguma forma mais fácil de fazer esse calculo de somar os pontos:

E estou tendo erro quando tento fazer forEach dessa forma: ERRO: Cannot read property 'forEach' of undefined

data.partidas.forEach(partida => {

                if (partida.placar_visitante > partida.placar_mandante) {   

                    const indexVisitante = times.findIndex(item => item.time === partida.visitante); 

                    let timeVisitante = times[indexVisitante];

                    timeVisitante.pontos += 3;
                    times[indexVisitante] = timeVisitante;
                }
        })

E a ultima duvida:

  • O array 2003.json, dentro dele, ele começa com partidas.
  • Depois é adicionado a variável const data para converter.
  • Porque para acessar a 1 rodada tem que fazer data[0] e não data.partidas[0].
  • Me perdi nessa parte de como acessar um arquivo json.

Obrigado.

Olá Daniel, tranquilo?

PORQUE: Ele faz timeVisitante = times[indexVisitante] e depois ao contrario times[indexVisitante] = timeVisitante, me perdi nessa logica.

Então, pode ficar tranquilo porque não teve lógica nenhuma nisso não hahahaha

Você pode comentar essas linhas que não vai mudar nada, pois podemos reparar no começo do código:

let timeVisitante = times[indexVisitante];

Então quando fazemos:

times[indexVisitante] = timeVisitante;

É completamente desnecessário, seria como fazer:

nome = "São Paulo"

novoNome = nome;

nome = NovoNome

Eu não entendi ainda essa logica, tem alguma forma mais fácil de fazer esse calculo de somar os pontos:

A maneira mais fácil, é como o professor fez:

  • Selecionamos o index do array com o findIndex
  • Pegamos o time no array com: times[index]

Dado que temos o time que é um objeto, com a pontuação:

  • time.pontuacao += 3

E ai poderíamos deletar essas linhas que eu citei :)

E estou tendo erro quando tento fazer forEach dessa forma: ERRO: Cannot read property 'forEach' of undefined

Opa, ai temos um ponto importante do javascript, o forEach só pode ser utilizado em um array!

E data.partida não é um array, na verdade nem existe, partida é algo que está dentro de cada elemento de data

Ou seja:

  • data[0].partida: Existe, pois estou pegando o primeiro elemento de data:
{
  partidas: [
    {
      visitante: 'Vasco',
      resultado: 'vitoria_mandante',
      data_partida: '29/03/2003',
      pontuacao_geral_mandante: [Object],
      placar_visitante: 2,
      hora_partida: '16h00',
      mandante: 'Guarani',
      placar_mandante: 4,
      estadio: 'Brinco de Ouro',
      pontuacao_geral_visitante: [Object]
    },
    {
      visitante: 'Grêmio',
      resultado: 'vitoria_mandante',
      data_partida: '29/03/2003',
      pontuacao_geral_mandante: [Object],
      placar_visitante: 0,
      hora_partida: '16h00',
      mandante: 'Atlético pr',
      placar_mandante: 2,
      estadio: 'Arena da Baixada',
      pontuacao_geral_visitante: [Object]
    },
    {
  • data.partida: Não existe pois data é apenas um array

Porque para acessar a 1 rodada tem que fazer data[0] e não data.partidas[0]. Me perdi nessa parte de como acessar um arquivo json.

Foi o que acabei de citar :)

O objeto do tipo data é um array de rodadas, dentro de cada rodada temos o elemento partidas, então na verdade o que temos:

data: [
{ partidas: [] },
{ partidas: [] },
{ partidas: [] },
{ partidas: [] }, 
]

Conseguiu Compreender ? Qualquer coisa estou a disposição!

Abraços e Bons Estudos :)