analisar data e número dos resultados da API

Oct 05 2020

Estou sugando campos de uma API que retorna uma matriz de campos. Cada campo da matriz é uma String que contém dois campos separados (um número e uma data). O número está entre parênteses e a data segue este e um espaço. A seguir está um exemplo do formato.

const data = [
            "(2) 2020-09-15", "(3) 2020-09-16"
        ];

Estou analisando este campo e armazenando os dados separadamente em meu aplicativo. Eu tenho meus próprios campos de números e datas que serão uma String em que cada número e data são separados por uma nova linha.

Estou conseguindo isso fazendo o seguinte.

let numbers = '', dates = numbers;

        for (let datum of data) {
            datum = datum.split(/[() ]/);
            numbers += `${datum[1]}\n`; dates += `${datum[3]}\n`;
        }

Veja um exemplo aqui .

Eu particularmente não gosto disso e gostaria de saber se há uma maneira mais eficiente e limpa de escrever isso.

Respostas

4 CertainPerformance Oct 05 2020 at 15:22

Em vez de declarar as variáveis ​​com let(você deve sempre preferirconst ) e concatenar e reatribuir, considere a criação de matrizes de números e datas, por exemplo:

[2, 3] e ["2020-09-15", "2020-09-16"]

Então, depois que o loop for concluído, junte todos os elementos por novas linhas.

Para a expressão regular, em vez de split, acho matchque seria mais apropriado. Você pode usar \((\d+)\) (\S+):

  • \( - literal (
  • (\d+) - 1º grupo de captura, composto por dígitos
  • \) - literal )
  • - espaço literal
  • (\S+) - 2º grupo de captura, composto por não espaços

Em seguida, extraia o primeiro e o segundo grupos de captura.

const data = [
  "(2) 2020-09-15", "(3) 2020-09-16"
];
const numbers = [];
const dates = [];
for (const item of data) {
  const [, number, date] = item.match(/\((\d+)\) (\S+)/);
  numbers.push(number);
  dates.push(date);
}
console.log(numbers.join('\n'));
console.log(dates.join('\n'));

3 SᴀᴍOnᴇᴌᴀ Oct 05 2020 at 15:54

Casos extremos

No mundo real, a entrada nem sempre é bem formada. O que acontece se houver um erro de digitação nos dados? Por exemplo:

const data = [
    "(2) 2020-09-15", "(3] 2020-09-16"
];

Isso fará com que undefinedapareça na saída para as datas. Em outros casos / frameworks / linguagens, uma exceção pode ser lançada que pode travar seu script / programa. Seria melhor se proteger contra tais cenários lançando um erro ou pelo menos pulando a adição de tais dados.


Clobbering variável

Na configuração do loop, datumé atribuída cada string em data:

for (let datum of data) {

Esta linha sobrescreve essa variável com uma matriz:

datum = datum.split(/[() ]/);

Isso é legal em JavaScript porque é digitado livremente. Mas pense em alguém lendo este código (incluindo o seu futuro!) Ao modificá-lo. E se você decidir mais tarde usar datumpara exibir a saída de forma diferente - você precisará determinar se é o datumque é uma string ou o datumque é uma matriz. Um nome de variável separado pode levar a menos confusão a esse respeito e também fornecer uma dica melhor sobre o que está na matriz - por exemplo parts, ou como é sugerido pela resposta de CertainPerformance, usar a atribuição de desestruturação pode ajudar a evitar esse cenário por completo.

1 AlexanderMashin Oct 05 2020 at 15:37

Eu usaria algo assim:

            const data = [
                "(2) 2020-09-15", "(3) 2020-09-16"
            ];

            let pairs = [];
            
            const regex = /^\((\d+)\)\s+(\d{4}-\d{2}-\d{2})$/;
            
            for (let datum of data) {
                // Idea from the previous answer:
                let pair = {};
                [, pair.number, pair.date] = regex.exec(datum);
                pairs.push (pair);
            }

            console.log(pairs);
Cada par de número e data é embalado como um objeto. A primeira vírgula em [, pair.number, pair.date]descarta toda a correspondência, que não é necessária.

Ao contrário da solução proposta pelo autor da pergunta, a data e o número relacionados são unidos em um objeto. Além disso, a divisão não é usada, pois depende dos detalhes do formato do texto que podem ser alterados posteriormente e semanticamente é melhor para extrair um número indefinido de fragmentos semelhantes do texto.