Zachowanie porządku z LINQ

Używam LINQ do obiektów instrukcji na uporządkowanej tablicy. Jakich operacji nie powinienem wykonać, aby upewnić się, że kolejność tablicy nie została zmieniona?

Author: Machavity, 2008-10-15

5 answers

Zbadałem metody Systemu.Linq.Enumerable , odrzucając wszelkie, które zwróciły nieenumerable wyniki. Sprawdziłem uwagi każdego z nich, aby określić, w jaki sposób kolejność wyniku będzie się różnić od kolejności źródła.

Zachowuje Porządek Absolutnie. Można odwzorować element źródłowy według indeksu na element wynikowy

  • AsEnumerable
  • Obsada
  • Concat
  • Wybierz
  • ToArray
  • ToList

Zachowuje Porządek. Elementy są filtrowane, ale nie zamawiane ponownie.

  • Distinct
  • z wyjątkiem
  • Intersect
  • OfType
  • Skip
  • SkipWhile
  • Take
  • TakeWhile
  • gdzie
  • Zip (nowy w. Net 4)

Niszczy porządek - nie wiemy, w jakiej kolejności oczekujemy rezultatów.

  • ToDictionary
  • ToLookup

Redefiniuje kolejność jawnie-użyj ich, aby zmienić kolejność wynik

  • OrderBy
  • OrderByDescending
  • rewers
  • ThenBy
  • ThenByDescending

Redefiniuje porządek zgodnie z pewnymi zasadami.

  • GroupBy - Obiekty IGrouping są generowane w kolejności opartej na kolejności elementów w source, które wytworzyły pierwszy klucz każdej IGrouping. Elementy w grupie są wyświetlane w kolejności, w jakiej występują w źródle.
  • GroupJoin - GroupJoin zachowuje kolejność elementów zewnętrznych i dla każdego elementu zewnętrznego, kolejność pasujących elementów z wnętrza.
  • Join-zachowuje kolejność elementów zewnętrznych, a dla każdego z tych elementów kolejność pasujących elementów wewnętrznych.
  • SelectMany - dla każdego elementu source wywoływany jest selektor i zwracany jest ciąg wartości.
  • Union - gdy obiekt zwracany tą metodą jest wyliczany, Union wylicza pierwszy i drugi w tej kolejności i zwraca każdy element, który jeszcze nie został poddał się.

Edit: przeniosłem się do zachowania porządku na podstawie tej implementacji .

    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;
    }
 546
Author: Amy B,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-11-17 16:56:31

Naprawdę mówisz o SQL, czy o tablicach? Mówiąc inaczej, czy używasz LINQ do SQL czy LINQ do obiektów?

Operatory LINQ to Objects w rzeczywistości nie zmieniają swojego oryginalnego źródła danych-budują sekwencje, które są skutecznie wspierane przez źródło danych. Jedynymi operacjami, które zmieniają kolejność są OrderBy/OrderByDescending/ThenBy/ThenByDescending - i nawet wtedy, są one stabilne dla równie uporządkowanych elementów. Oczywiście, wiele operacji będzie filtrować niektóre elementy, ale zwracane elementy będą w tej samej kolejności.

Jeśli przekonwertujesz do innej struktury danych, np. z ToLookup lub ToDictionary, nie wierzę, że porządek jest zachowany w tym momencie - ale to i tak jest nieco inne. (Kolejność mapowania wartości do tego samego klucza jest jednak zachowana dla wyszukiwania, jak sądzę.)

 29
Author: Jon Skeet,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-10-15 12:24:00

Jeśli pracujesz nad tablicą, brzmi to tak, jakbyś używał LINQ-to-Objects, a nie SQL; możesz to potwierdzić? Większość operacji LINQ niczego nie porządkuje (wyjście będzie w tej samej kolejności co wejście) - więc nie stosuj innego sortowania (OrderBy[malejąco]/ThenBy[malejąco]).

LINQ tworzy nową sekwencję , pozostawiając tylko oryginalne DANE]

Zauważ, że wpychanie danych do Dictionary<,> (ToDictionary) spowoduje szyfrowanie danych, jak słownik nie respektuje żadnej konkretnej kolejności sortowania.

Ale najczęstsze rzeczy (Wybierz, gdzie, Pomiń, weź) powinny być w porządku.

 6
Author: Marc Gravell,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-10-15 12:25:09

Znalazłem świetną odpowiedź w podobnym pytaniu, które odwołuje się do oficjalnej dokumentacji. Cytuję:

Dla metod Enumerable (LINQ to Objects, które stosuje się do List<T>), można polegać na kolejności elementów zwracanych przez Select, Where, lub GroupBy. Nie dotyczy to rzeczy, które z natury nie są uporządkowane, jak ToDictionary lub Distinct.

Z GroupBy dokumentacja:

IGrouping<TKey, TElement> obiekty są ułożone w kolejności elementy w źródle, które tworzyły pierwszy klucz każdego IGrouping<TKey, TElement>. Elementy w grupie są wyświetlane w kolejności, w jakiej występują w source.

Niekoniecznie jest to prawdą dla IQueryable metod rozszerzeń(innych dostawców LINQ).

Source: czy metody liniowe LINQ ' a utrzymują względny porządek elementów?

 3
Author: Curtis Yallop,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 11:54:53

Dowolne 'group by' lub 'order by' może zmienić kolejność.

 2
Author: leppie,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-10-15 12:53:11