2015-09-25 7 views
6

Ho un elenco di oggetti con più proprietà al suo interno. Ecco l'oggetto.Rimuovi tutto tranne 1 oggetto nell'elenco basato sul raggruppamento

public class DataPoint 
{ 
    private readonly string uniqueId; 
    public DataPoint(string uid) 
    { 
     this.uniqueId = uid; 
    } 

    public string UniqueId 
    { 
     get 
     { 
      return this.uniqueId; 
     } 
    } 

    public string ScannerID { get; set; } 

    public DateTime ScanDate { get; set; } 
} 

Ora nel mio codice, ho una lista gigante di questi, centinaia forse qualche migliaio.

Ogni oggetto punto dati appartiene a un tipo di scanner e ha una data di scansione. Voglio rimuovere tutti i punti di dati che sono stati scansionati lo stesso giorno tranne l'ultimo per un dato computer.

Ho provato a utilizzare LINQ come segue ma questo non ha funzionato. Ho ancora molti punti dati duplicati.

this.allData = this.allData.GroupBy(g => g.ScannerID) 
        .Select(s => s.OrderByDescending(o => o.ScanDate)) 
        .First() 
        .ToList();` 

ho bisogno di raggruppare i punti dati per ID scanner, perché ci potrebbero essere punti di dati digitalizzati lo stesso giorno, ma su una macchina diversa. Ho solo bisogno dell'ultimo punto dati per un giorno se ce ne sono molti.

Modifica per chiarimento - Per punto di dati ultimo si intende l'ultimo punto di dati scansionato per una determinata data di scansione per una determinata macchina. Spero che aiuti. Quindi, quando si raggruppa per ID scanner, ho quindi cercato di ordinare per data di scansione e quindi mantenere solo l'ultima data di scansione per giorni con più scansioni.

Ecco alcuni dati di test per 2 macchine:

Unique ID Scanner ID  Scan Date 
A1JN221169H07 49374 2003-02-21 15:12:53.000 
A1JN22116BK08 49374 2003-02-21 15:14:08.000 
A1JN22116DN09 49374 2003-02-21 15:15:23.000 
A1JN22116FP0A 49374 2003-02-21 15:16:37.000 
A1JOA050U900J 80354 2004-10-05 10:53:24.000 
A1JOA050UB30K 80354 2004-10-05 10:54:39.000 
A1JOA050UD60L 80354 2004-10-05 10:55:54.000 
A1JOA050UF80M 80354 2004-10-05 10:57:08.000 
A1JOA0600O202 80354 2004-10-06 08:38:26.000 
+1

Si sa che si può fare una proprietà auto di sola lettura e sbarazzarsi del campo di supporto 'stringa pubblica UniqueId {get; set privato; } '. – juharr

+0

Si dovrebbero anche inserire i risultati desiderati per i dati di test. – juharr

risposta

5

Voglio rimuovere eventuali punti di dati che sono stati analizzati lo stesso giorno, tranne che per l'ultimo per una determinata macchina.

quindi immagino che si desidera raggruppare sia ScanDate e ScannerID. Ecco il codice:

var result = dataPoints.GroupBy(i => new { i.ScanDate.Date, i.ScannerID }) 
         .OrderByDescending(i => i.Key.Date) 
         .Select(i => i.First()) 
         .ToList(); 
+0

ordinerà 'ScanDate' in modo da poter utilizzare' Last'? – ieaglle

+0

Questo si raggrupperà in base a 'ScanDate' e' ScannerID', se per l'ultimo indica l'ultimo valore inserito, questo è sufficiente ma se si intende l'ultimo per data, quindi devo modificare la mia risposta. –

+1

Penso che tu voglia effettivamente raggruppare su "i.ScanDate.Date" da quando l'OP ha detto _scanned nello stesso giorno_. Quindi ordina per 'ScanDate'. – juharr

-1

Proprio come un a parte, la classe potrebbe essere definito come

public class DataPoint 
{ 
    public DataPoint(string uid) 
    { 
    UniqueId = uid; 
    } 

public string UniqueId {get; private set; } 
public string ScannerID { get; set; } 
public DateTime ScanDate { get; set; } 

}

+1

Questo dovrebbe essere un commento invece di una risposta. Un po 'come il commento che ho già fatto. – juharr

+0

@juharr, scusa stavo scrivendo quando hai aggiunto il commento. Tuttavia, volevo mostrare quanto meno linee di codice dovessero essere necessarie, il che è molto importante per un commento. Questo è il motivo per cui ho aggiunto "Proprio come una parte". –

1

Se ho capito si correttamente questo è ciò che si desidera.

var result = dataPoints.GroupBy(i => new { i.ScanDate.Date, i.ScannerID }) 
         .Select(i => i.OrderBy(x => x.ScanDate).Last()) 
         .ToList(); 

This gruppi nel id scanner e il giorno (SacnnerDate.Date saranno azzerare la parte di tempo), allora per ogni raggruppamento esso ordini dal ScanDate (poiché i gruppi sono lo stesso giorno questo ordine sul tempo) e prende l'ultimo. Quindi per ogni giorno otterrai un risultato per ogni scanner che ha l'ultimo ScanDate per quel particolare giorno.