2010-03-14 13 views

risposta

46
int minAccountLevel = int.MaxValue; 
int maxAccountLevel = int.MinValue; 
foreach (DataRow dr in table.Rows) 
{ 
    int accountLevel = dr.Field<int>("AccountLevel"); 
    minAccountLevel = Math.Min(minAccountLevel, accountLevel); 
    maxAccountLevel = Math.Max(maxAccountLevel, accountLevel); 
} 

Sì, questo è davvero il modo più veloce. L'utilizzo delle estensioni Linq Min e Max sarà sempre più lento perché è necessario ripetere l'iterazione due volte. Potresti potenzialmente usare Linq Aggregate, ma la sintassi non sarà molto più carina di questa.

+0

Sì, questo è quello che suggerisce SLaks, da utilizzare per il ciclo come il modo più veloce. – Ahmed

+0

Sì, ma penso che dovrebbe essere { int accountLevel = dr.Field ("AccountLevel"); min = Math.Min (min, accountLevel); max = Math.Max ​​(max, accountLevel); } non è vero? – Ahmed

+0

@Ahmed: Spiacente, errore di battitura nei compiti delle variabili. Fisso. – Aaronaught

6

Il modo più efficace per fare questo (che ci crediate o no) è quello di rendere due variabili e scrivere un ciclo for.

12

Utilizzare LINQ. Funziona bene su datatables, purché si converta la raccolta di righe in un oggetto IEnumerable.

List<int> levels = AccountTable.AsEnumerable().Select(al => al.Field<int>("AccountLevel")).Distinct().ToList(); 
int min = levels.Min(); 
int max = levels.Max(); 

cura per risolvere la sintassi; è complicato quando si utilizza LINQ su DataTable e anche le funzioni di aggregazione sono divertenti.

Sì, può essere eseguito con una query, ma è necessario generare un elenco di risultati, quindi utilizzare .Min() e .Max() come funzioni di aggregazione in istruzioni separate.

+0

Ma richiede due iterazioni. – SLaks

+0

Questo codice funziona correttamente? – Ahmed

+0

In qualche modo non penso che 'Distinct' lo renderà più veloce - deve cancellare ogni elemento, mentre' Min' e 'Max' basta fare un confronto. – Aaronaught

5
var answer = accountTable.Aggregate(new { Min = int.MinValue, Max = int.MaxValue }, 
             (a, b) => new { Min = Math.Min(a.Min, b.Field<int>("AccountLevel")), 
                 Max = Math.Max(a.Max, b.Field<int>("AccountLevel")) }); 
int min = answer.Min; 
int max = answer.Max; 

1 iterazione, stile LINQ :)

+0

non l'ho ancora provato, ma sembra promettente - l'hai confrontato con la scala per loop per le prestazioni? – Alex

+0

che tipo è 'accountTable'? Gli oggetti DataTable non sembrano supportare 'Aggregate' per me ... – hdgarrood

84

approccio Easiar sulla DataTable potrebbe essere:

int minLavel = Convert.ToInt32(dt.Compute("min([AccountLevel])", string.Empty)); 
+1

Questo è l'approccio migliore ma manca una cosa l'uso di' [] 'nel codice sopra .. es. ' int minLavel = Converti. ToInt32 (dt.Compute ("min ([AccountLevel])", string.Empty)); ' Senza le parentesi quadre mi ha dato un errore. –

+0

Questo. Lascia che il motore di dati faccia il lavoro per te! –

0

io non so come la mia soluzione a confronto le prestazioni saggio risposte precedenti.

Capisco che la domanda iniziale era: Qual è il modo più veloce per ottenere valori minimi e massimi in un oggetto DataTable, questo può essere un modo per farlo:

DataView view = table.DefaultView; 
view.Sort = "AccountLevel"; 
DataTable sortedTable = view.ToTable(); 
int min = sortedTable.Rows[0].Field<int>("AccountLevel"); 
int max = sortedTable.Rows[sortedTable.Rows.Count-1].Field<int>("AccountLevel"); 

E 'un modo semplice per raggiungere lo stesso risultato senza loop. Ma le prestazioni dovranno essere confrontate con le risposte precedenti. Il pensiero che amo Cylon Cats risponde di più.

4

un altro modo di fare questo è

int minLavel = Convert.ToInt32(dt.Select("AccountLevel=min(AccountLevel)")[0][0]); 

Non sono sicuro da parte performace, ma questo non fa dare l'uscita corretta

5

Questo ha funzionato bene per me

int max = Convert.ToInt32(datatable_name.AsEnumerable() 
         .Max(row => row["column_Name"])); 
1
var min = dt.AsEnumerable().Min(row => row["AccountLevel"]); 
var max = dt.AsEnumerable().Max(row => row["AccountLevel"]); 
+0

Aggiungi un commento alla tua risposta, il codice non può essere chiaro. –

+0

Grazie, ma in questo caso il codice lo spiega da solo. –

1

Per quanto riguarda le prestazioni, questo dovrebbe essere comparabile. Utilizzare Seleziona istruzione e Ordina per ottenere un elenco e quindi selezionare il primo o l'ultimo (in base al proprio criterio di ordinamento).

var col = dt.Select("AccountLevel", "AccountLevel ASC"); 

var min = col.First(); 
var max = col.Last(); 
1
Session["MinDate"] = dtRecord.Compute("Min(AccountLevel)", string.Empty); 
Session["MaxDate"] = dtRecord.Compute("Max(AccountLevel)", string.Empty); 
+4

Forse puoi approfondire ** perché ** questo è il modo più veloce? Qualsiasi argomento può essere utile per gli altri a prendere o saltare il tuo consiglio a favore di altri post. –

Problemi correlati