Я використовую LINQ для вказівки щодо об'єктів впорядкованому масиві. Які операції не слід робити, щоб переконатися, що порядок масиву не змінився?
Я використовую LINQ для вказівки щодо об'єктів впорядкованому масиві. Які операції не слід робити, щоб переконатися, що порядок масиву не змінився?
Відповіді:
Я вивчив методи System.Linq.Eumerable , відкинувши будь-які результати, що принесли не-численні результати. Я перевірив зауваження кожного, щоб визначити, як порядок результату відрізнятиметься від порядку джерела.
Зберігає замовлення абсолютно. Ви можете зіставити вихідний елемент за індексом до результату
Зберігає орден. Елементи фільтруються або додаються, але не переупорядковуються.
Знищує замовлення - ми не знаємо, в якому порядку очікувати результатів.
Повторно визначає порядок - використовуйте їх, щоб змінити порядок результату
Переосмислює замовлення за деякими правилами.
Редагувати. Я перемістив "Розрізнення" на збереження порядку на основі цієї реалізації .
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
методу) просто означала сказати "несортовано", а не "в непередбачуваному порядку". Я б сказав, що Distinct
належить до вищевказаної категорії фільтрування Where
.
Ви насправді говорите про SQL чи про масиви? Інакше кажучи, ви використовуєте LINQ для SQL або LINQ для об'єктів?
Оператори LINQ для об'єктів насправді не змінюють свого початкового джерела даних - вони будують послідовності, які ефективно підтримуються джерелом даних. Єдиними операціями, які змінюють впорядкування, є OrderBy / OrderByDescending / thenBy / thenByDescending - і навіть тоді вони стабільні для однаково упорядкованих елементів. Звичайно, багато операцій будуть фільтрувати деякі елементи, але повернені елементи будуть у тому ж порядку.
Якщо ви конвертуєте в іншу структуру даних, наприклад, з ToLookup або ToDictionary, я не вважаю, що порядок зберігається в цій точці - але це все одно дещо інше. (Порядок відображення значень із тим самим ключем зберігається для пошуку, хоча, я вважаю.)
GroupBy
потім SelectMany
дадуть результати , згруповані по ключу, але не в порядку зростання ключа ... він дасть їх у тому порядку , в якому ключі спочатку мали місце.
list<x> {a b c d e f g}
якщо c, d, e всі мають один і той же ключ, то отримана послідовність буде містити c, d, e поруч один з одним І в порядку c, d, e. Я не можу знайти категоричну відповідь на основі МС.
Якщо ви працюєте над масивом, це здається, що ви використовуєте LINQ до об'єктів, а не SQL; ви можете підтвердити? Більшість операцій LINQ нічого не здійснюють повторне замовлення (вихід буде в тому ж порядку, що і вхідний), тому не застосовуйте інший сорт (OrderBy [спадаючий] / потімBy [низхідний]).
[ред .: як Джон висловився чіткіше; LINQ зазвичай створює нову послідовність, залишаючи вихідні дані в спокої]
Зауважте, що натискання даних у Dictionary<,>
(ToDictionary) скомпонує дані, оскільки словник не дотримується певного порядку сортування.
Але найпоширеніші речі (Select, Where, Skip, Take) мають бути добре.
ToDictionary()
просто не обіцяє замовлення, але на практиці підтримує порядок введення (поки ви щось не вилучите з нього). Я не кажу, щоб покладатися на це, але "скремблінг" здається неточним.
Я знайшов чудову відповідь у подібному питанні, яке посилається на офіційну документацію. Щоб його цитувати:
Для Enumerable
методів (LINQ до об'єктів, який відноситься до List<T>
), ви можете покладатися на порядок елементів , що повертаються Select
, Where
або GroupBy
. Це не відноситься до речей, які по своїй природі невпорядкованих як ToDictionary
або Distinct
.
З документації Enumerable.GroupBy :
Ці
IGrouping<TKey, TElement>
об'єкти отримані в порядку , заснованому на порядок елементів в джерелі , які збудували перший ключ кожногоIGrouping<TKey, TElement>
. Елементи в групуванні виводяться в порядку, в якому вони відображаютьсяsource
.
Це не обов'язково стосується IQueryable
методів розширення (інших постачальників LINQ).
Джерело: Чи підтримують численні методи LINQ відносний порядок елементів?
Питання тут конкретно стосується LINQ до об'єктів.
Якщо ви використовуєте LINQ-to-SQL, замість цього немає порядку, якщо ви не накладете його на щось подібне:
mysqlresult.OrderBy(e=>e.SomeColumn)
Якщо ви цього не зробите з LINQ-SQL, то порядок результатів може змінюватися між наступними запитами, навіть одних і тих же даних, що може спричинити помилку, що переривається.