2010-03-14 27 views

Respuesta

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í, esta es realmente la manera más rápida. El uso de las extensiones de Linq Min y Max siempre será más lento porque debe repetir dos veces. Puede utilizar Linq Aggregate, pero la sintaxis no va a ser mucho más bonita de lo que ya es.

+0

Sí, esto es lo que sugiere SLaks, utilizar para bucle como la manera más rápida. – Ahmed

+0

Sí, pero creo que debería ser { int accountLevel = dr.Field ("AccountLevel"); min = Math.Min (min, accountLevel); max = Math.Max ​​(max, accountLevel); } ¿no es así? – Ahmed

+0

@Ahmed: Disculpa, error en las asignaciones de variables. Fijo. – Aaronaught

6

La forma más eficiente de hacer esto (aunque no lo crean) es hacer que dos variables y escribir un bucle for.

12

Utilice LINQ. Funciona muy bien en las tablas de datos, siempre que convierta la colección de filas a un IEnumerable.

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

Editado para corregir la sintaxis; es complicado cuando se usa LINQ en DataTables, y las funciones de agregación también son divertidas.

Sí, se puede hacer con una consulta, pero deberá generar una lista de resultados, luego usar .Min() y .Max() como funciones de agregación en instrucciones separadas.

+0

Pero requiere dos iteraciones. – SLaks

+0

¿Este código funciona correctamente? – Ahmed

+0

De alguna manera, no creo que 'Distinct' acelere esto, tiene que manipular todos los elementos, mientras que' Min' y 'Max' solo hacen una comparación. – 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 iteración, el estilo de LINQ :)

+0

aún no lo he probado, pero parece prometedor. ¿Lo has comparado con el de arriba? lazo para el rendimiento? – Alex

+0

¿de qué tipo es 'accountTable'? Los objetos DataTable no parecen admitir 'Aggregate' para mí ... – hdgarrood

84

enfoque Easiar en tabla de datos podría ser:

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

Este es el mejor enfoque, pero le falta una cosa, el uso de' [] 'en el código anterior ... ej. ' int minLavel = Convert. ToInt32 (dt.Compute ("min ([AccountLevel])", string.Empty)); ' Sin los corchetes me dio un error. –

+0

Esto. Deje que el motor de datos haga el trabajo por usted. –

0

no sé cómo mi solución compara el rendimiento prudente respuestas anteriores.

entiendo que la pregunta inicial fue: ¿Cuál es la manera más rápida para obtener valores mínimo y máximo en un objeto DataTable, esta puede ser una forma de hacerlo:

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"); 

Es una manera fácil de lograr el mismo resultado sin bucle. Pero el rendimiento deberá ser comparado con las respuestas anteriores. Pensé que me encantaría que los gatos de Cylon respondieran más.

4

otra forma de hacer esto es

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

No estoy seguro por parte performace pero esto sí da la salida correcta

5

Esto funcionó bien para mí

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

Agregue un comentario sobre su respuesta, el código no puede ser claro. –

+0

Gracias, pero en este caso, explíqueme el código. –

1

En cuanto al rendimiento, esto debería ser comparable. Use Seleccionar declaración y Ordenar para obtener una lista y luego elija la primera o la última (según su orden de clasificación).

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

Tal vez puedas explicar ** por qué ** esta es la manera más rápida? Cualquier argumento puede ser útil para que otros tomen u omitan su consejo a favor de las otras publicaciones. –

Cuestiones relacionadas