"Peeking Ahead" during a cycle through dictionary entries

It seems like it should be something very simple, but every time I come up with this problem I end up w / solutions that feel "less elegant"

Here is my main question: if I go through the dictionary that I ordered in a certain way at any given point in the loop, how can I β€œpeek” or get a link to an element of the word β€œx” in front of the current element without changing the current counter? For instance:

Dim tempDictionary = New Dictionary(Of String, String) tempDictionary.Add("TestName1", "TestValue1") tempDictionary.Add("TestName2", "TestValue2") tempDictionary.Add("TestName3", "TestValue3") '... and so on ... ' For Each Item In tempDictionary DoStuff(Item) 'Here is the point in which I want to see what the value of the' 'dictionary item that is 1, 2, 3, [x] places in front of the current' 'item without interfering w/ the current loop.' 'CODE' Next 

Thanks in advance!

+4
source share
7 answers

It sounds like you need c-style for a loop. Sorry C # here (since you asked in VB)

 for (int i = 0; i < myArray.Length; i++) { object current = myArray[i]; if(i + 1 < myArray.Length) { // make sure there is a next item object nextItem = myArray[i + 1] } } 

As already mentioned, the dictionary is not ordered, but you can put the keys in an array to use above.

+1
source

The problem is that Dictionary not an ordered data structure. You cannot count on the order in which items are listed in the dictionary. If you need the necessary elements, you must adhere to the general List or use a third-party ordered dictionary (for example, Wintellect Power Collections has one).

Actually, there is an OrderedDictionary in System.Collections.Specialized, but it is not generic.

If you want to create your own generic ordered dictionary, this CodeProject article might be of interest to you.

+4
source

Here you can look ahead. Regarding order, I will not repeat what others have already mentioned.

 Dim peek As Integer = 2 ''// peek ahead amount For i As Integer = 0 To tempDictionary.Count - 1 Dim key = tempDictionary.Keys(i) Dim value = tempDictionary.Values(i) Console.WriteLine("{0} : {1}", key, value) Dim peekIndex As Integer = i + peek If peekIndex < tempDictionary.Count - 1 Then Dim nextKey = tempDictionary.Keys(peekIndex) Dim nextValue = tempDictionary.Values(peekIndex) Console.WriteLine("Peek: {0} : {1}", nextKey, nextValue) End If Next 
+1
source

What you are asking is pointless because the order in which the elements are returned is undefined. There is no such thing as order.

0
source

The only ways I could think of is to create a copy of the current counter and push it forward (which obviously becomes pretty ugly) or use the .skip() method from Linq to create an enumerable that works in front and then concatenates both using some kind of a combination method that you will again need to determine yourself.

At another point: in order to have a meaningful order of elements, you probably want to use System.Generics.SortedDictionary instead of the standard one.

This method should work to combine the two ienumerables given an adequate adder method

  public static IEnumerable<TResult> Combine<TParam1, TParam2, TResult>(this IEnumerable<TParam1> self, IEnumerable<TParam2> other, Func<TParam1, TParam2, TResult> combiner) { using(var first=self.GetEnumerator()) using (var second = other.GetEnumerator()) { while (first.MoveNext() && second.MoveNext()) yield return combiner(first.Current, second.Current); } } 

I can’t guarantee that this will work just like that, because I had to cut the code from the source fragment

Edit: with a little thought on this, this might be what you want: (unfortunately in C #, since my vb is not so good):

 skippedEnumerable = myEnumerable; myEnumerable.Select(item => {skippedEnumerable = skippedEnumerable.Skip(1); return new KeyValuePair<T, IEnumerable<T>>(item, skippedEnumerable )}); 

This will give you a couple of the current item and an enumerable run at the current position, so you can use .ElementAt () to easily offset to that enumerated. This may cause the enumerations to be deep enough, so it is probably (or maybe not due to O (n ^ 2)) it is better to use myEnumerable.Skipe(index) directly;

0
source

I don't know what you want to do with the entry into the dictionary, but something like this should work:

 Dim dict As New Dictionary(Of String, String) For i As Integer = 0 To dict.Count - 2 If dict.ElementAt(i).Equals(dict.ElementAt(i + 1)) Then Exit For Next 

ElementAt () - Linq function. However, if you repeat this list, I really wonder if the dictionary is useful. A regular list could be better.

0
source

Most likely, you need to create an array with the keys from the dictionary in the order you need and iterate through the indices.

That is, your for loop will be the equivalent of vb for (int i = 0; i <array.length; i ++), and you will look up the values ​​of the dictionary with the dictionary [array [i]]. Of course, you could replace me with i + 1 (with border checking).

0
source

All Articles