【问题标题】:SortedList and LinqSortedList 和 Linq
【发布时间】:2017-05-09 13:47:43
【问题描述】:

在阅读了有关将 Linq 与 SortedList 结合使用时会发生什么的文档后,我感到很困惑。

https://msdn.microsoft.com/en-us/library/ms132319(v=vs.110).aspx

我猜枚举是保证排序的,也可以按索引检索,但是 Values 和 Keys 呢?所有这些情况都安全吗?

        var list = new SortedList<DateTime, object>();

        //add entries here ...

        var firstValue1 = list.Values[0];
        var firstValue2 = list.First().Value;
        var firstValue3 = list.Values.First();

        var firstKey1 = list.Keys[list.Count-1];
        var firstKey2 = list.First().Key;
        var firstKey3 = list.Keys.First();

        var sortedList = list.Where(x => x.Key > DateTime.Now)
            .Select(x => x.Value);

【问题讨论】:

  • @EpicKip 它会准确地告诉你你得到了什么。枚举中的第一项。在很多情况下,这正是您所需要的。
  • @EpicKip:如果您对底层项目一无所知,那么您可能是对的,但在这种情况下,它是一个排序列表。你得到一个非常具体的东西。最早的项目,最新的项目,得分最高的项目......无论您的排序是什么,都定义了第一个项目是什么。你还会认为写.OrderBy(x=&gt;x.Thing).First()没有意义吗?
  • @EpicKip 如果你不喜欢使用SortedList,那就说那个。说使用First 会给你一个“随机”元素,而客观上这样做是完全错误的。说你不喜欢 SortedList 的设计(和一般的集合,从它的声音来看)以及它对你的代码的作用是一个意见问题,非常欢迎你持有。
  • @EpicKip:您应该确切地知道您的排序列表正在排序...该框架不只是选择一个随机项目来对您的列表进行排序,您可以准确地告诉它您想要什么。 .. 我怀疑你知道这一点,这只能归结为意见分歧。
  • @Chris 当然,没关系,我觉得我对我的 cmets 有点太仓促了,可能没有说出我想说的话,感谢您与像我这样的头脑发热并保持 100% 文明;)

标签: c# sortedlist


【解决方案1】:

阅读文档...

来自documentation on the Values property

IList&lt;T&gt;中的值顺序与SortedList&lt;TKey, TValue&gt;中的顺序相同。”

来自documentation on the Keys property

IList&lt;T&gt;中键的顺序与SortedList&lt;TKey, TValue&gt;中的顺序相同。”

【讨论】:

  • 谢谢,我的疑虑消失了。 :)
【解决方案2】:

你可以在这里查看源代码:

https://referencesource.microsoft.com/#System/compmod/system/collections/generic/sortedlist.cs,de670561692e4a20

显然,Keys 属性只是该类实例的包装器:

https://referencesource.microsoft.com/#System/compmod/system/collections/generic/sortedlist.cs,374aa21b960ae2e2

如果您查看GetEnumerator() 方法,您会发现它创建了一个SortedListKeyEnumerator。这是它的源代码:

https://referencesource.microsoft.com/#System/compmod/system/collections/generic/sortedlist.cs,a4492235f85c77d8

据我所知,MoveNext() 只是遍历包含的 SortedList 的键。

您可以了解Values 的工作原理。

【讨论】:

  • 源代码可以更改,文档保证不会。 :)
  • @Stig 文档保证也会更改,只是不太频繁。 C# 和 .NET 之前确实做出了重大改变,尽管很少。
【解决方案3】:

如果您查看 Enumerable.cs 的源代码,您会发现没有谓词的重载只是尝试将源视为 IList,如果这不起作用,它将使用枚举器返回第一个元素。索引和枚举器都应该由 SortedList 类在内部处理,以便您获得适当的(排序的)结果:

public static TSource First<TSource>(this IEnumerable<TSource> source) {
            if (source == null) throw Error.ArgumentNull("source");
            IList<TSource> list = source as IList<TSource>;
            if (list != null) {
                if (list.Count > 0) return list[0];
            }
            else {
                using (IEnumerator<TSource> e = source.GetEnumerator()) {
                    if (e.MoveNext()) return e.Current;
                }
            }
            throw Error.NoElements();
        }

带有谓词的重载的工作方式略有不同,它使用枚举器对每个项目执行谓词,寻找第一个匹配项:

    public static TSource First<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate) {
        if (source == null) throw Error.ArgumentNull("source");
        if (predicate == null) throw Error.ArgumentNull("predicate");
        foreach (TSource element in source) {
            if (predicate(element)) return element;
        }
        throw Error.NoMatch();
    }

无论哪种方式,您都应该得到相同的(排序的)结果。

【讨论】:

    猜你喜欢
    • 2011-07-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-18
    • 1970-01-01
    • 1970-01-01
    • 2011-07-07
    • 1970-01-01
    相关资源
    最近更新 更多