Reputation: 1036
I'm passing a SortedDictionary array to a function and I need to loop over the items in the dictionary. If it's the first item, do X, else for all other items in the dictionary, do Y.
SortedDictionary<string,int> eventsArray
Found this but it's not working:
foreach (var eventItem in eventsArray)
{
if (eventsArray.Keys.First())
item.firstStuff();
else if (items.Last() == item)
item.lastStuff();
item.otherStuff();
}
Upvotes: 0
Views: 77
Reputation: 74345
You can do something like this:
SortedDictionary<string,int> dict = new SortedDictionary<string,int>();
IEnumerator<KeyValuePair<string,int>> dictWalker = dict.GetEnumerator();
if ( !dictWalker.MoveNext() )
{
ProcessFirstItem( dictWalker.Current ) ;
while ( !dictWalker.MoveNext() )
{
ProcessOtherItems(dictWalker.Current) ;
}
}
Or you could make it a generic LINQ extension, like this:
public static class Extensions
{
public static IEnumerable<T> Apply<T>( this IEnumerable<T> sequence , Action<T> firstAction , Action<T> middleAction , Action<T> lastAction )
{
IEnumerator<T> visitor = sequence.GetEnumerator();
bool hasCurr = visitor.MoveNext() ;
T curr = hasCurr ? visitor.Current : default(T) ;
bool hasNext = visitor.MoveNext() ;
T next = hasNext ? visitor.Current : default(T) ;
Action<T> noop = x => {} ;
Action advance = () => {
hasCurr = hasNext ;
curr = next ;
hasNext = visitor.MoveNext();
next = hasNext ? visitor.Current : default(T) ;
} ;
firstAction = firstAction ?? noop ;
middleAction = middleAction ?? noop ;
lastAction = lastAction ?? noop ;
if ( hasCurr )
{
firstAction(curr);
yield return curr;
advance();
}
while ( hasCurr && hasNext )
{
middleAction(curr) ;
yield return curr;
advance();
}
if ( hasCurr )
{
lastAction(curr);
yield return curr;
advance();
}
if ( hasCurr || hasNext ) { throw new InvalidOperationException("Well, this is embarassing now, isn't it?"); }
}
}
Cheers!
Upvotes: 0
Reputation: 1002
Quality Catalyst tried to base a solution off your description. And since it's not clear whether you want behavior described in your description, or in the example you shared, here's a jab at what it seems like you are trying to accomplish in the example:
var firstItem = eventsArray.First();
var lastItem = eventsArray.Last();
foreach (var eventItem in eventsArray)
{
if (eventItem.Key == firstItem.Key)
item.firstStuff();
else if (eventItem.Key == lastItem.Key)
item.lastStuff();
else
item.otherStuff();
}
However it's very hard to discern what item
is in this example, but because your eventItem is a string, I assume this is close to what you want.
Upvotes: 1
Reputation: 6795
You said:
If it's the first item, do X, else for all other items in the dictionary, do Y.
In this case you don't need to check for the last item. Try this: it is simple, readable and fast:
bool isFirstItem = true; // when we enter the loop we know we deal with the first item
foreach (var eventItem in eventsArray)
{
if (isFirstItem)
{
item.firstStuff();
isFirstItem = false; // next item we deal with is not the first item
}
else
item.otherStuff();
}
Upvotes: 3