Ho avuto un'interessante domanda di intervista l'altro giorno, con cui ho davvero faticato. Le specifiche (molto ambiziose) mi impongono di scrivere, in C#, parser per due diversi flussi di dati. Ecco un esempio di made-up del primo flusso:Elaborazione di un formato di feed di dati
30=EUR/USD,35=3,50=ON,51=12.5,52=13.5,50=6M,51=15.4,52=16.2,50=1Y,51=17.2,52=18.3
dove 30 è la coppia di valute, 35 è il numero di tenori, e 50,51,52 sono il tenore, offerta e chiedere, rispettivamente. L'offerta e la richiesta sono facoltative, ma una tupla tenore-bid-chiesta corretta avrà almeno uno dei due prezzi. Il codice del framework che hanno fornito implicava che il risultato dell'analisi di questa riga fosse costituito da 3 singoli oggetti (istanze DataElement). Ho finito con una dichiarazione di switch piuttosto spiacevole e un'implementazione basata su loop che non sono sicuro abbia funzionato.
Quali tecniche ci sono per leggere questo tipo di flusso? Ho cercato di capire qualcosa con la ricorsione, cosa che non potevo avere ragione.
MODIFICA: In base alla risposta di @ evanmcdonnall (accettata), ecco il codice completo di compilazione e di lavoro, nel caso sia utile per chiunque altro.
List<DataElement> Parse(string row)
{
string currency=string.Empty;
DataElement[] elements = null;
int j = 0;
bool start = false;
string[] tokens = row.Split(',');
for (int i = 0; i < tokens.Length; i++)
{
string[] kv = tokens[i].Split('=');
switch (kv[0])
{
case "30":
currency = kv[1];
break;
case "35":
elements = new DataElement[int.Parse(kv[1])];
break;
case "50":
if (start)
j++;
elements[j] = new DataElement() { currency = currency, tenor = kv[1] };
start = true;
break;
case "51":
elements[j].bid = double.Parse(kv[1]);
break;
case "52":
elements[j].ask = double.Parse(kv[1]);
break;
}
}
return elements.ToList();
}
I concetti principali sono:
- Avere un contatore separato per il "ciclo interno" di ripetere elementi in ciascuna linea
- Avere un flag booleano per indicare quando che "ciclo interno" inizia
- Assegnare la matrice di oggetti per memorizzare i risultati del "ciclo interno" nel punto in cui è nota la lunghezza (ad esempio, tag 50)
- Per semplicità e chiarezza, avere una funzione che legge solo un singolo linea, quindi chiamarla più volte da una funzione separata.
Non sembra come questo è un flusso di dati delimitato, né larghezza fissa. Penserei che il tuo metodo sembra ragionevole –
l'ordine degli elementi è sempre lo stesso? Intendo prima che avrai la coppia di valute, poi il numero di tenori e, successivamente, il numero esatto di tuple corrispondenti al numero di tenori? – ppetrov
@AndrewWalters: sembra delimitato in modo abbastanza coerente con ',' ... – mellamokb