Сохранение заказа с помощью LINQ

Я использую инструкции LINQ to Objects для упорядоченного массива. Какие операции не следует делать, чтобы убедиться, что порядок массива не изменился?

вопрос задан 15.10.2008
Matthieu Durut
2095 репутация

5 ответов


  • 543 рейтинг

    Я исследовал методы системы . Linq. Enumerable , отбрасывая все, которые возвращали не IEnumerable результаты. Я проверил замечания каждого из них, чтобы определить, как порядок результата будет отличаться от порядка источника.

    Сохраняет заказ Абсолютно. Вы можете сопоставить исходный элемент по индексу с результирующим элементом

    • AsEnumerable
    • В ролях
    • Конкат
    • Выбрать
    • ToArray
    • ToList

    Заказ Пресервов. Элементы фильтруются, но не переупорядочиваются.

    • Отличный
    • За исключением
    • Пересечь
    • OfType
    • Пропустить
    • SkipWhile
    • Возьми
    • TakeWhile
    • Где
    • Zip (новый в. нетто 4)

    Уничтожает ордер - мы не знаем, в каком порядке ожидать результатов.

    • ToDictionary
    • ToLookup

    Переопределяет порядок явно - используйте их для изменения порядка результата

    • Заказать по
    • OrderByDescending
    • Реверс
    • ThenBy
    • ThenByDescending

    Переопределяет заказ в соответствии с некоторыми правилами.

    • GroupBy - объекты IGrouping выдаются в порядке, основанном на порядке элементов в источнике, который создал первый ключ каждой IGrouping. Элементы в группировке выдаются в порядке их появления в источнике.
    • GroupJoin - GroupJoin сохраняет порядок элементов external, а для каждого элемента external - порядок соответствия элементов из inner.
    • Соединение - сохраняет порядок элементов external, а для каждого из этих элементов порядок сопоставления элементов inner.
    • SelectMany - для каждого элемента источника вызывается селектор и возвращается последовательность значений.
    • Union - при перечислении объекта, возвращаемого этим методом, Union перечисляет первый и второй в этом порядке и возвращает каждый элемент, который еще не был получен.

    Редактировать: Я переместил Distinct в порядок сохранения на основе этой реализации .

        private static IEnumerable DistinctIterator
          (IEnumerable source, IEqualityComparer comparer)
        {
            Set set = new Set(comparer);
            foreach (TSource element in source)
                if (set.Add(element)) yield return element;
        }
    
    ответ дан Amy B, с репутацией 85482, 15.10.2008
  • 29 рейтинг

    Вы на самом деле говорите о SQL или о массивах? Другими словами, используете ли вы LINQ to SQL или LINQ to Objects?

    Операторы LINQ to Objects на самом деле не изменяют свой исходный источник данных - они создают последовательности, которые эффективно поддерживаются источником данных. Единственными операциями, которые изменяют порядок, являются OrderBy / OrderByDescending / ThenBy / ThenByDescending - и даже тогда они стабильны для одинаково упорядоченных элементов. Конечно, многие операции отфильтровывают некоторые элементы, но возвращаемые элементы будут в том же порядке.

    Если вы преобразуете в другую структуру данных, e. г. с ToLookup или ToDictionary я не верю, что порядок сохраняется в этот момент - но это все равно несколько иначе. (Порядок отображения значений для одного и того же ключа сохраняется для поиска, хотя, я полагаю. )

    ответ дан Jon Skeet, с репутацией 1057123, 15.10.2008
  • 6 рейтинг

    Если вы работаете с массивом, похоже, что вы используете LINQ-to-Objects, а не SQL; Можешь подтвердить? Большинство операций LINQ ничего не упорядочивают (выходные данные будут в том же порядке, что и входные), поэтому не применяйте другую сортировку (OrderBy [Descending] / ThenBy [Descending]).

    [править: как выразился Джон; Обычно LINQ создает новую последовательность , оставляя только исходные данные]

    Обратите внимание, что помещение данных в Dictionary<,> (ToDictionary) приведет к шифрованию данных, поскольку словарь не учитывает какой-либо конкретный порядок сортировки.

    Но наиболее распространенные вещи (выбрать, где, пропустить, взять) должны быть в порядке.

    ответ дан Marc Gravell, с репутацией 759786, 15.10.2008
  • 3 рейтинг

    Я нашел отличный ответ на аналогичный вопрос, который ссылается на официальную документацию. Процитирую это:

    Для методов Enumerable (LINQ to Objects, который относится к List) вы можете положиться на порядок элементов, возвращаемых Select, Where или GroupBy. Это не относится к вещам, которые по своей природе неупорядочены, как ToDictionary или Distinct.

    Из Перечислим. Документация GroupBy :

    Объекты IGrouping выдаются в порядке, основанном на порядке элементов в источнике, который создал первый ключ каждого из IGrouping. Элементы в группировке даются в том порядке, в котором они появляются в source.

    Это не обязательно верно для методов расширения IQueryable (других поставщиков LINQ).

    Источник: Поддерживают ли перечисляемые методы LINQ относительный порядок элементов?

    ответ дан Curtis Yallop, с репутацией 4014, 11.06.2014
  • 2 рейтинг

    Любая 'group by' или 'order by', возможно, изменит порядок.

    ответ дан leppie, с репутацией 95570, 15.10.2008