Solucionado (ver solução)
Solucionado
(ver solução)
1
resposta

[Projeto] Aula 2 Mão na massa: usando o reduce, utilizei a lib stopword para controle de palavras

Dei uma patina em como importar e usar stopword mas ta aí, primeiro tinha usado um array com as palavras a serem excluidas mas não me parecia bom solução final a seguir:

import fs from 'fs'; // Importa o módulo fs para interagir com o sistema de arquivos
import { removeStopwords, porBr } from 'stopword'; // Importa o módulo para excluir palavras como 'a', 'o', 'e' etc

const caminhoArquivo = process.argv;

// Lê um arquivo de forma assíncrona e retorna uma Promise
function lerArquivo(caminho) {
// Lê o arquivo e retorna o conteúdo em formato de string. Poderia usar try catch com async/await ao invés de new Promise para melhorar clareza
    return new Promise((resolve, reject) => {
        fs.readFile(caminho, 'utf-8', (erro, dados) => {
            if (!erro) {
                resolve(dados);
              // Caso ocorra um erro, lança uma exceção mais específica  
            } else if(erro.code === 'ENOENT') {
                erro.message = `Arquivo não encontrado em: ${caminho}`;
                reject(erro);                 
            } else {
                erro.message = 'Erro desconhecido';
                reject(erro);
            }
        }); 
    });
}

function exibeResultado(texto) {
    const paragrafos = extraiParagrafo(texto);
    const resultado  = processaParagrafo(paragrafos);
    return resultado;
}

function extraiParagrafo (texto) {
    return texto.toLowerCase() // convert para caixa baixa evitar palavras como Produto e produto serem diferenciadas
    .split('\n') // Separa cada paragrafo na quebra de linha
}

function processaParagrafo(texto) {
    return texto.reduce((resultadoFinal, paragrafo) => { // Itera cada paragrafo sem precisar criar arrays intermediarios e evita achatamentos desnecessarios
            if(paragrafo.trim() !== '') { // verifica se uma linha não tem apenas espaços
                resultadoFinal.indexParagrafo++; // controle para exibir em qual paragrafo as palavras se repetem
                const palavrasDuplicadas = filtraPalavrasDuplicadas(paragrafo); // Recebe objeto contendo palavras:incidência
                // Se houver palavras duplicadas, adiciona ao array de resultados
                adicionarPalavrasDuplicadosNoAcumulador(resultadoFinal, palavrasDuplicadas, resultadoFinal.indexParagrafo); 
            }
            return resultadoFinal;
        }, { indexParagrafo: 0, resultados: [] })  // acumulador objeto contendo o index do paragrafo e um array para incluir os objetos(palavras repitidas)
        .resultados   // retorna apenas o array resultados e não o objeto inteiro
}
function removeCaracterEspecial(palavra) {
    // remove caracteres com exceção acentos e ç
    return palavra.replace(/[^\w\sáàâãéèêíïóôõöúçñ]/g, '');
}
function adicionarPalavrasDuplicadosNoAcumulador(resultadoFinal, palavrasDuplicadas, indexParagrafo) {
    if (Object.keys(palavrasDuplicadas).length) {
        resultadoFinal.resultados.push({
        idParagrafo: indexParagrafo,
        palavrasDuplicadas: palavrasDuplicadas
        }); // no array resultados adiciona um objeto com o número do paragrafo e um array de objetos contendo as palavras repetidas.
    }    
}

function filtraPalavrasDuplicadas(paragrafo) {
    const contagem = verificaPalavrasDuplicadas(paragrafo); // Obtém todas as palavras e suas incidencias no paragrafo
    const palavrasDuplicadas = {} // cria um objeto vazio que vai receber os atributos(palavras) e seu valor(ocorrências)
    //Itera sobre cada chave do objeto retornado
    Object.entries(contagem).forEach(([palavra, qtd]) => {
        if(qtd > 1) {
            palavrasDuplicadas[palavra] = (palavrasDuplicadas[palavra] || 0) + qtd;
        }
    });
    return palavrasDuplicadas;
}

function verificaPalavrasDuplicadas(texto) {
    const listaPalavras = texto.split(' ');
    // Remover as stopwords da lista de palavras
    const listaFiltrada = removeStopwords(listaPalavras, porBr)

    const resultado = {};
    // Verifica o número de ocorrencias para cada palavra no paragrafo
    listaFiltrada.forEach(palavra => { 
        const palavraNova = removeCaracterEspecial(palavra);
        resultado[palavraNova] = (resultado[palavraNova] || 0) + 1;      
    });

    return resultado;
}

// Chama a função lerArquivo e trata a Promise
lerArquivo(caminhoArquivo[2].toString())
  .then(texto => {
    console.log(exibeResultado(texto));
  })
  .catch(erro => {
    console.error('Erro:', erro.message);
  });
1 resposta
solução!

Olá Israel! Joia?

Que legal ver você explorando o uso da biblioteca stopword no seu projeto! Parece que você está no caminho certo ao utilizar o reduce para processar os parágrafos e identificar palavras duplicadas.

A biblioteca stopword é realmente útil para limpar o texto de palavras comuns que não agregam muito valor à análise.

Bons estudos!