First item in a SortedDictionary?

情到浓时终转凉″ 提交于 2019-12-20 03:30:06

问题


There are many, many threads on ways to get the "first" item from a Dictionary, and various answers as to why such a thing is not really a good idea because there's no internal ordering. But mine's a SortedDictionary, so those arguments don't apply. Yet I cannot find a way to get the Nth item from a SortedDictionary any easier than a Dictionary.

Here is my SD:

FRs As SortedDictionary(Of DateTime, ScheduleItem)

I see a few hints that I should be able to do:

If FRs.Count = 1 Then
    FirstFR = FRs.Keys(0)

But that is not valid in my code - it says it has no defaults and cannot be indexed. .First and other options appear to all be in LINQ, which I cannot target. So is there any simple way to access it in this fashion?

Note: any solution offered must not use LINQ, which does not exist on many non-Wintel platforms.


回答1:


The problem is that a SortedDictionary is indeed ordered by the key. But that does not mean that you can access it via index. So if you can't use LINQ:

Dim firstFR As KeyValuePair(Of DateTime, ScheduleItem)
For Each kv In FRs
    firstFR = kv
    Exit For
Next

Otherwise you could simply use First/ FirstOrDefault.

Sidenote: since a KeyValuePair(Of Tkey, TValue) is a structure, therefore a value type, it is never null/Nothing. You could check for an empty dictionary in this ugly way:

If firstFR.Equals(New KeyValuePair(Of DateTime, ScheduleItem))
    Console.WriteLine("Empty dictionary")
End If 

So it's much more readable to use If FRs.Count = 0 Then ....


Update: if you just want the key or value at a given index you can use:

Dim firstSchedule As Date = FRs.Keys(0)

or the first Date in it:

Dim firstDate As ScheduleItem = FRs.Values(0)

On this way you could actually get both via index even without LINQ:

Dim firstFR = new KeyValuePair(Of DateTime, ScheduleItem)(FRs.Keys(0), FRs.Values(0))

Disclaimer: according to my question here this works only if you have imported System.Linq, then Enumerable.ElementAt is used implicitly which enumerates a sequence to find an item via index if the type doesn't implement IList(Of T). So don't use it in this case.




回答2:


Linq is mostly just a series of extension methods, so you can write own:

Imports System
Imports System.Collections.Generic
Imports System.Runtime.CompilerServices

Public Module EnumerableExtensions

    <Extension()> 
    Public Function FirstValue(Of TKey, TValue)(source As SortedDictionary(Of TKey, TValue)) As TValue
        For Each kvp In source
            Return kvp.Value
        Next
        Return Nothing
    End Function

End Module

Public Module Module1
    Public Sub Main()
        Dim a As SortedDictionary(Of string, string) = new SortedDictionary(Of string, string)
        a.Add("foo", "1 - foo")
        a.Add("bar", "2 - bar")
        Console.WriteLine(a.FirstValue())
    End Sub
End Module

Here's the example running in dotnetfiddle.



来源:https://stackoverflow.com/questions/36918321/first-item-in-a-sorteddictionary

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!