2016-04-28 3 views
2

Есть много, много темы о способах получить «первый» элемент от Dictionary и различные ответы на вопрос, почему такая вещь не очень хорошая идея, потому что нет внутреннего заказа. Но мой - SortedDictionary, поэтому эти аргументы не применяются. Тем не менее, я не могу найти способ получить N-й элемент от SortedDictionary легче, чем Dictionary.Первый элемент в сортированном документе?

Вот мой SD:

FRs As SortedDictionary(Of DateTime, ScheduleItem) 

Я вижу несколько намеков, что я должен быть в состоянии сделать:

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

Но это не действует в моем коде - это не говорит, что это не имеет по умолчанию и не может быть проиндексирован. .First и другие варианты отображаются в LINQ, к которым я не могу настроить таргетинг. Так есть ли простой способ получить к нему доступ таким образом?

Примечание: любое предлагаемое решение не должно использовать LINQ, который не существует на многих платформах, отличных от Wintel.

ответ

5

Проблема в том, что ключ SortedDictionary действительно заказан. Но это не означает, что вы можете получить доступ к нему через индекс. Так что, если вы не можете использовать LINQ:

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

В противном случае вы могли бы просто использовать First/FirstOrDefault.

Sidenote: так как KeyValuePair(Of Tkey, TValue) является структурой, поэтому тип значения, он никогда не null/Nothing. Вы можете проверить пустой словарь в этом уродливом виде:

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

Так что гораздо более удобным для чтения использовать If FRs.Count = 0 Then ....


Update: если вы просто хотите, ключ или значение по указанному индексу вы можете использовать:

Dim firstSchedule As Date = FRs.Keys(0) 

или первый Date в нем:

Dim firstDate As ScheduleItem = FRs.Values(0) 

Таким образом, вы можете получить оба индекса даже без LINQ:

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

Отказ от ответственности: в соответствии с my question here это работает только если вы импортировали System.Linq, то Enumerable.ElementAt используется неявно, который перечисляет последовательность, чтобы найти элемент, если тип не реализует IList(Of T) с помощью индекса.Поэтому не используйте его в этом случае.

+0

Хорошо спасибо Тиму. Опять другой «что они думали». На самом деле, действительно нет причин, по которым они не могли бы сделать это, если есть дефолт? –

+0

@MauryMarkowitz: посмотрите на мою часть _update_. –

+0

Это не работает в моем коде, я получаю сообщение об отсутствии значения по умолчанию или индекса. Если быть точным: «Public Overloads ReadOnly Ключи свойств как SortedDictionary (Of Date, ScheduleItem) .KeyCollection» не имеет параметров, и его тип возврата не может быть проиндексирован –

2

Linq в основном только ряд методов расширения, так что вы можете написать собственное:

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 

Вот пример работает в dotnetfiddle.