Uso las instrucciones de LINQ to Objects en una matriz ordenada. ¿Qué operaciones no debo hacer para asegurarme de que no se cambie el orden de la matriz?
361
Examiné los métodos de System.Linq.Enumerable , descartando cualquiera que arrojara resultados no IEnumerable. Revisé los comentarios de cada uno para determinar cómo el orden del resultado diferiría del orden de la fuente.
Preserva el orden absolutamente. Puede asignar un elemento fuente por índice a un elemento resultado
Preserva el orden. Los elementos se filtran o agregan, pero no se reordenan.
Destruye el orden: no sabemos en qué orden esperar resultados.
Redefine el orden explícitamente: utilícelos para cambiar el orden del resultado
Redefine el orden de acuerdo con algunas reglas.
Editar: He movido Distinct a Preserve order basado en esta implementación .
private static IEnumerable<TSource> DistinctIterator<TSource>
(IEnumerable<TSource> source, IEqualityComparer<TSource> comparer)
{
Set<TSource> set = new Set<TSource>(comparer);
foreach (TSource element in source)
if (set.Add(element)) yield return element;
}
Distinct
método) solo significaba "sin clasificar", no "en orden impredecible". Yo diría queDistinct
pertenece a la categoría de filtrado anterior, al igual queWhere
.¿Estás hablando realmente de SQL o de matrices? Para decirlo de otra manera, ¿estás usando LINQ to SQL o LINQ to Objects?
Los operadores de LINQ to Objects en realidad no cambian su fuente de datos original: construyen secuencias que están respaldadas efectivamente por la fuente de datos. Las únicas operaciones que cambian el orden son OrderBy / OrderByDescending / ThenBy / ThenByDescending, y aun así, son estables para elementos igualmente ordenados. Por supuesto, muchas operaciones filtrarán algunos elementos, pero los elementos que se devuelven estarán en el mismo orden.
Si convierte a una estructura de datos diferente, por ejemplo, con ToLookup o ToDictionary, no creo que se mantenga el orden en ese punto, pero de todos modos eso es algo diferente. (Creo que el orden de asignación de valores a la misma clave se conserva para las búsquedas).
fuente
GroupBy
seguido deSelectMany
dará los resultados agrupados por clave, pero no en orden ascendente de la clave ... los dará en el orden en que ocurrieron las claves originalmente.list<x> {a b c d e f g}
si c, d, e tienen la misma clave, la secuencia resultante contendrá c, d, e una al lado de la otra Y en el orden c, d, e. Parece que no puedo encontrar una respuesta categórica basada en MS.Si está trabajando en una matriz, parece que está utilizando LINQ-to-Objects, no SQL; ¿puedes confirmar? La mayoría de las operaciones de LINQ no reordenan nada (la salida estará en el mismo orden que la entrada), así que no aplique otro tipo (OrderBy [Descending] / ThenBy [Descending]).
[editar: como Jon puso más claramente; LINQ generalmente crea una nueva secuencia, dejando solo los datos originales]
Tenga en cuenta que
Dictionary<,>
insertar los datos en un (ToDictionary) codificará los datos, ya que el diccionario no respeta ningún orden de clasificación en particular.Pero las cosas más comunes (Seleccionar, Dónde, Saltar, Tomar) deberían estar bien.
fuente
ToDictionary()
simplemente no hace promesas sobre el orden, sino que en la práctica mantiene el orden de entrada (hasta que elimine algo de él). No estoy diciendo que confíe en esto, pero 'revolver' parece inexacto.Encontré una gran respuesta en una pregunta similar que hace referencia a la documentación oficial. Para citarlo:
Para
Enumerable
métodos (LINQ a objetos, que se aplica aList<T>
), se puede confiar en el orden de los elementos devueltos porSelect
,Where
oGroupBy
. Este no es el caso para cosas que son inherentemente desordenadas comoToDictionary
oDistinct
.Esto no es necesariamente cierto para los
IQueryable
métodos de extensión (otros proveedores de LINQ).Fuente: ¿Los métodos enumerables de LINQ mantienen el orden relativo de los elementos?
fuente
Cualquier 'agrupar por' u 'ordenar por' posiblemente cambiará el orden.
fuente
La pregunta aquí se refiere específicamente a LINQ-to-Objects.
Si usa LINQ-to-SQL en su lugar, no hay orden allí a menos que imponga uno con algo como:
Si no hace esto con LINQ-to-SQL, el orden de los resultados puede variar entre consultas posteriores, incluso de los mismos datos, lo que podría causar un error intermitente.
fuente