analizzare la data e il numero dai risultati dell'API

Oct 05 2020

Sto mangiando i campi da un'API che restituisce un array di campi. Ogni campo dell'array è una stringa che contiene effettivamente due campi separati (un numero e una data). Il numero è racchiuso tra parentesi e segue la data e uno spazio. Quello che segue è un esempio del formato.

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

Sto analizzando questo campo e quindi memorizzo i dati separatamente nella mia app. Ho i miei numeri e campi di date che saranno una stringa in cui ogni numero e data è separato da una nuova riga.

Sto raggiungendo questo obiettivo facendo quanto segue.

let numbers = '', dates = numbers;

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

Vedi un esempio qui .

Non mi piace particolarmente e mi chiedo se esista un modo più efficiente e più pulito per scriverlo.

Risposte

4 CertainPerformance Oct 05 2020 at 15:22

Piuttosto che dichiarare le variabili con let(dovresti sempre preferireconst ) e concatenare e riassegnare, considera invece la creazione di matrici di numeri e date, ad esempio:

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

Quindi, dopo che il ciclo è terminato, unisci tutti gli elementi con una nuova riga.

Per l'espressione regolare, piuttosto che split, penso matchsarebbe più appropriato. Puoi usare \((\d+)\) (\S+):

  • \( - letterale (
  • (\d+) - 1 ° gruppo di cattura, composto da cifre
  • \) - letterale )
  • - spazio letterale
  • (\S+) - 2 ° gruppo di cattura, composto da non spazi

Quindi estrai il primo e il secondo gruppo di acquisizione.

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

Casi di bordo

Nel mondo reale, l'input non è sempre ben formato. Cosa succede se c'è un errore di battitura nei dati? Per esempio:

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

Questo porterà ad undefinedapparire nell'output per le date. In altri casi / framework / linguaggi potrebbe essere generata un'eccezione che potrebbe causare il crash del tuo script / programma. Sarebbe meglio proteggersi da tali scenari lanciando un errore o almeno saltando l'aggiunta di tali dati.


Clobbering variabile

Nella configurazione del loop, datumogni stringa viene assegnata in data:

for (let datum of data) {

Questa riga sovrascrive quella variabile con un array:

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

Questo è legale in JavaScript perché è digitato in modo approssimativo. Ma pensa a chiunque legga questo codice (incluso il tuo sé futuro!) Quando modifichi questo codice. Cosa succede se in seguito decidi di utilizzare datumper visualizzare l'output in modo diverso - dovresti determinare se si datumtratta di una stringa o di datumun array. Un nome di variabile separato potrebbe portare a meno confusione a tale riguardo e fornire anche un suggerimento migliore su ciò che è nell'array - ad esempio parts, o come suggerito dalla risposta di CertainPerformance, l'uso dell'assegnazione destrutturante può aiutare a evitare completamente quello scenario.

1 AlexanderMashin Oct 05 2020 at 15:37

Userei qualcosa del genere:

            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);
Ogni coppia di numeri e date è confezionata come un oggetto. La prima virgola in [, pair.number, pair.date]scarta l'intera corrispondenza, che non è necessaria.

A differenza della soluzione proposta dall'autore della domanda, la data e il numero relativi sono uniti in un unico oggetto. Inoltre, la divisione non viene utilizzata, poiché si basa sui dettagli del formato del testo che può cambiare in seguito e semanticamente si adatta meglio all'estrazione di un numero indefinito di frammenti simili dal testo.