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

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

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

Допустим, SomeVariable равно 1. Я хочу получить последний item.value из первых трех индексов (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

person user2322507    schedule 26.06.2014    source источник
comment
Словари не имеют порядка, поэтому нет надежного способа получить первые 3 inidices.   -  person D Stanley    schedule 26.06.2014
comment
я читал это... я предполагаю, что все еще хочу попробовать это.   -  person user2322507    schedule 26.06.2014
comment
Ну как вы хотите, чтобы он был заказан? Если у вас есть что заказать ключи словаря, мы могли бы вам помочь   -  person IEatBagels    schedule 26.06.2014
comment
@TopinFrassi ... заказ не проблема. к счастью, заказано так, как я хочу. поэтому мне просто нужна помощь с кодом или его структурой.   -  person user2322507    schedule 26.06.2014


Ответы (3)


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

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

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

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.

person Ňɏssa Pøngjǣrdenlarp    schedule 26.06.2014
comment
+1. Согласованный. Он сказал, что все равно хочет попробовать, поэтому я просто дал ему ответ, но вы правы в том, что это не рекомендуется. - person nickles80; 26.06.2014
comment
да, он также сказал, что читал это, я подумал, что покажу, почему это очень плохая идея и насколько плоха. даже если это просто поиск, поскольку он не указан, это означает, что он может сломаться в более новых версиях. - person Ňɏssa Pøngjǣrdenlarp; 26.06.2014
comment
поэтому +1 от меня. - person nickles80; 27.06.2014

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

Что-то вроде этого.

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

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

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

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

person nickles80    schedule 26.06.2014

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

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

foreach( KeyValuePair<int,string> kvp in dict) { ... }
person T McKeown    schedule 26.06.2014