c# - 使用LINQ维护订单




arrays sorting data-structures (5)

我检查了System.Linq.Enumerable的方法,放弃了返回非IEnumerable结果的任何方法。 我检查了每一个的评论,以确定结果的顺序将如何与来源的顺序不同。

完全保留订单。 您可以通过索引将源元素映射到结果元素

  • AsEnumerable
  • CONCAT
  • 选择
  • ToArray的
  • ToList

保留订单。 元素被过滤,但不被重新排序。

  • 不同
  • 相交
  • OfType
  • 跳跃
  • SkipWhile
  • 采取
  • TakeWhile
  • 哪里
  • Zip(新的.NET 4)

破坏秩序 - 我们不知道按期望结果的顺序。

  • ToDictionary
  • 去查查看

明确重新定义订单 - 使用这些更改结果的顺序

  • 排序依据
  • OrderByDescending
  • 相反
  • ThenBy
  • ThenByDescending

根据一些规则重新定义订单。

  • GroupBy - 根据产生每个IGrouping的第一个键的源中元素的顺序,IGrouping对象的顺序排序。 分组中的元素按它们在源代码中出现的顺序排序。
  • GroupJoin - GroupJoin保留外部元素的顺序,并且对于每个外部元素,从内部匹配元素的顺序。
  • 加入 - 保留外部元素的顺序,并且对于这些元素中的每一个元素,内部元素的匹配顺序。
  • SelectMany - 对于源的每个元素,调用选择器并返回一系列值。
  • Union - 枚举此方法返回的对象时,Union按该顺序枚举第一个和第二个,并产生尚未产生的每个元素。

编辑:我已经移动了基于这个implementation保持顺序不同。

    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指令。 我应该做哪些操作来确保数组的顺序没有改变?


你真的在谈论SQL,还是关于数组? 换句话说,你是使用LINQ to SQL还是LINQ to Objects?

LINQ to Objects运算符实际上并没有改变它们的原始数据源 - 它们构建了由数据源有效支持的序列。 唯一改变顺序的操作是OrderBy / OrderByDescending / ThenBy / ThenByDescending - 即便如此,那些对于同等顺序的元素也是稳定的。 当然,很多操作都会过滤掉一些元素,但是返回的元素将会以相同的顺序排列。

如果你转换为不同的数据结构,例如使用ToLookup或ToDictionary,我不认为顺序在这一点上保留 - 但是这有点不同。 (我相信,虽然映射到同一个键的值的顺序被保留用于查找。)


如果你正在处理一个数组,那听起来你正在使用LINQ到对象,而不是SQL; 你可否确认? 大多数LINQ操作不会重新排序(输出的顺序与输入顺序相同) - 因此不要应用其他排序(OrderBy [Descending] / ThenBy [Descending])。

[编辑:正如Jon所说的更清楚; LINQ通常会创建一个新的序列,只保留原始数据]

请注意,将数据推送到Dictionary<,> (ToDictionary)将扰乱数据,因为字典不尊重任何特定的排序顺序。

但最常见的事情(选择,地点,跳过,采取)应该没问题。


我在一个引用官方文档的类似问题中找到了很好的答案。 引用它:

对于Enumerable方法(LINQ to Objects,适用于List<T> ),您可以依赖SelectWhereGroupBy返回的元素的顺序。 对于像ToDictionaryDistinct这样天生无序的事物,情况并非如此。

来自Enumerable.GroupBy文档:

IGrouping<TKey, TElement>对象按照产生每个IGrouping<TKey, TElement>的第一个键的源中元素的顺序排序。 分组中的元素按它们在source出现的顺序排序。

对于IQueryable扩展方法(其他LINQ提供者),这不一定是正确的。

来源: LINQ的Enumerable方法保持元素的相对顺序吗?


该解决方案也可能有帮助:

Array.prototype.grep = function (key, value) {
    var that = this, ret = [];
    this.forEach(function (elem, index) {
        if (elem[key] === value) {
            ret.push(that[index]);
        }
    });
    return ret.length < 2 ? ret[0] : ret;
};
var bar = myArray.grep("id","45");

我使它像$.grep ,如果找到一个对象, 函数将返回该对象,而不是数组。





c# arrays linq sorting data-structures