我在一个有序数组上使用LINQ to Objects指令。 我不应该做哪些操作来确保数组的顺序没有改变?
当前回答
我在一个类似的问题中找到了一个很好的答案,它引用了官方文件。引用一下:
对于可枚举方法(LINQ to Objects,适用于List<T>),您可以依赖于Select、Where或GroupBy返回的元素顺序。对于像ToDictionary或Distinct这样固有无序的对象则不是这样。
可列举的。GroupBy文档: 根据源中产生每个IGrouping<TKey, TElement>的第一个键的元素的顺序,生成IGrouping<TKey, TElement>对象。分组中的元素是按照它们在源代码中出现的顺序生成的。
对于IQueryable扩展方法(其他LINQ提供程序)则不一定如此。
来源:LINQ的可枚举方法是否保持元素的相对顺序?
其他回答
我在一个类似的问题中找到了一个很好的答案,它引用了官方文件。引用一下:
对于可枚举方法(LINQ to Objects,适用于List<T>),您可以依赖于Select、Where或GroupBy返回的元素顺序。对于像ToDictionary或Distinct这样固有无序的对象则不是这样。
可列举的。GroupBy文档: 根据源中产生每个IGrouping<TKey, TElement>的第一个键的元素的顺序,生成IGrouping<TKey, TElement>对象。分组中的元素是按照它们在源代码中出现的顺序生成的。
对于IQueryable扩展方法(其他LINQ提供程序)则不一定如此。
来源:LINQ的可枚举方法是否保持元素的相对顺序?
我检查了System.Linq的方法。可枚举的,丢弃返回非ienumerable结果的任何结果。我检查了每一个的注释,以确定结果的顺序与源的顺序有什么不同。
绝对维护秩序。可以通过索引将源元素映射到结果元素
AsEnumerable 投 Concat 选择 ToArray ToList
保持秩序。元素被过滤或添加,但不重新排序。
截然不同的 除了 相交 减低 Prepend (.net 4.7.1新增功能) 跳过 SkipWhile 取 TakeWhile 在哪里 Zip (.net 4中的新功能)
破坏秩序——我们不知道结果的顺序。
ToDictionary ToLookup
显式重定义顺序-使用这些来改变结果的顺序
订购者 按降序排序 反向 然后通过 然后降序
根据某些规则重新定义Order。
GroupBy - The IGrouping objects are yielded in an order based on the order of the elements in source that produced the first key of each IGrouping. Elements in a grouping are yielded in the order they appear in source. GroupJoin - GroupJoin preserves the order of the elements of outer, and for each element of outer, the order of the matching elements from inner. Join - preserves the order of the elements of outer, and for each of these elements, the order of the matching elements of inner. SelectMany - for each element of source, selector is invoked and a sequence of values is returned. Union - When the object returned by this method is enumerated, Union enumerates first and second in that order and yields each element that has not already been yielded.
编辑:基于此实现,我已经将不同移动到保留顺序。
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;
}
这里的问题特别指的是LINQ-to-Objects。
如果你使用LINQ-to-SQL而不是没有秩序,除非你强加一个像这样的东西:
mysqlresult.OrderBy(e=>e.SomeColumn)
如果不对LINQ-to-SQL执行此操作,则后续查询的结果顺序可能会不同,即使是相同的数据,这可能会导致间歇性错误。
任何“group by”或“order by”都可能改变顺序。
如果你正在处理一个数组,听起来像是你在使用LINQ-to-Objects,而不是SQL;你能否证实?大多数LINQ操作不会对任何东西重新排序(输出将与输入的顺序相同)-所以不要应用另一种排序(OrderBy[降序]/ThenBy[降序])。
[编辑:乔恩说得更清楚;LINQ通常创建一个新的序列,而不影响原始数据。
注意,将数据推入Dictionary<,> (ToDictionary)将打乱数据,因为Dictionary不尊重任何特定的排序顺序。
但大多数常见的事情(选择,在哪里,跳过,采取)应该是好的。
推荐文章
- equals vs Arrays。Java中的等号
- 如何计算一个NumPy bool数组中的真实元素的数量
- 如何找到一个值的数组索引?
- Python csv字符串到数组
- 在c#中从URI字符串获取文件名
- 检查SqlDataReader对象中的列名
- 如何将类标记为已弃用?
- c# 8支持。net框架吗?
- Linq-to-Entities Join vs GroupJoin
- 为什么字符串类型的默认值是null而不是空字符串?
- 在list中获取不同值的列表
- 组合框:向项目添加文本和值(无绑定源)
- 如何为ASP.net/C#应用程序配置文件值中的值添加&号
- 从System.Drawing.Bitmap中加载WPF BitmapImage
- 如何找出一个文件存在于c# / .NET?