Для каждого словарного цикла в порядке индекса

#vb.net #dictionary #foreach #keyvaluepair

#vb.net #словарь #foreach #keyvaluepair

Вопрос:

Я попробовал свои силы, используя for цикл с Dictionary , но не смог добиться того, чего хочу.

У меня есть определенная переменная SomeVariable , и по значению этой переменной я хочу, чтобы моя foreach работала. SomeVariable может быть 1,2,3 or 4

Итак, допустим SomeVariable 1 , я хочу получить последний item.value из первых 3 индексов (0,1,2) внутри SomeCollection .

И если SomeVariable 2 я хочу получить последний item.value из следующих 3 индексов (3,4,5) внутри SomeCollection .

И так далее…

 For Each item As KeyValuePair(Of String, Integer) In SomeCollection
    If SomeVariable = 1 Then
            //....
    ElseIf SwitchCount = 2 Then
           //....
    End If
Next
  

Комментарии:

1. Словари не имеют порядка, поэтому нет надежного способа получить «первые 3» идентификатора.

2. я прочитал это … я предполагаю, что я все равно захочу попробовать.

3. Ну, как вы хотите, чтобы это было упорядочено? Если у вас есть что-то для упорядочивания словарных ключей, мы могли бы вам помочь

4. @TopinFrassi … упорядочение не является проблемой. к счастью, он упорядочен так, как я хочу. так что мне просто нужна помощь с кодом или его структурой.

Ответ №1:

Словарь не имеет определенного порядка, поэтому любой воспринимаемый вами порядок является временным. Из MSDN:

Порядок ключей в .Сбор ключей не указан, но это тот же порядок, что и связанные значения в .ValueCollection, возвращаемые свойством Values .

Попытка использовать коллекцию ключей для определения порядка показывает, насколько он временный:

 Dim myDict As New Dictionary(Of Integer, String)

For n As Int32 = 0 To 8
    myDict.Add(n, "foo")
Next

For n As Int32 = 0 To myDict.Keys.Count - 1
    Console.WriteLine(myDict.Keys(n).ToString)
Next
  

на выходе выводится от 0 до 8 в порядке, как и следовало ожидать. затем:

 myDict.Remove(5)
myDict.Add(9, "bar")

For n As Int32 = 0 To myDict.Keys.Count - 1
    Console.WriteLine(myDict.Keys(n).ToString)
Next
  

Вывод: 0, 1, 2, 3, 4, 9 (!), 6, 7, 8

Как вы можете видеть, он повторно использует старые слоты. Любой код, зависящий от того, что должно находиться в определенном месте, в конечном итоге сломается. Чем больше вы добавляете / удаляете, тем более неупорядоченным он становится. Если вам нужен порядок Dictionary использования SortedDictionary вместо этого.

Комментарии:

1. 1. Согласовано. Он сказал, что все равно хочет попробовать, поэтому я просто дал ему ответ, но вы правы в том, что это нежелательно.

2. да, он также сказал, что прочитал это, я подумал, что покажу, почему это очень плохая идея и насколько плохая. даже если это просто поиск, поскольку он «не указан», это означает, что он может сломаться в более новых версиях.

3. отсюда 1 от меня.

Ответ №2:

Вы не можете получить доступ к словарю по индексу, но вы можете получить доступ к коллекции ключей по индексу. Для этого вам вообще не нужен цикл.

Итак, что-то вроде этого.

 If SomeVariable = 1 Then
    Return SomeCollection(SomeCollection.Keys(2))
ElseIf SomeVariable = 2 Then 
    ...
End If
  

Если он действительно структурирован, вы могли бы сделать это:

 Return SomeCollection(SomeCollection.Keys((SomeVariable * 3) - 1))
  

Вероятно, вам потребуется некоторая проверка ошибок и проверка правильности длины словаря, но это должно направить вас на правильный путь.

Ответ №3:

Вы всегда можете использовать общий SortedDictionary, я использую только C #, так что вот мой пример:

 SortedDictionary<int,string> dict = new SortedDictionary<int, string>();

foreach( KeyValuePair<int,string> kvp in dict) { ... }