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);
});