Given the code ..
var dictionary = new Dictionary<string, string>{
开发者_如何学JAVA { "something", "something-else" },
{ "another", "another-something-else" }
};
dictionary.ForEach( item => {
bool isLast = // ... ?
// do something if this is the last item
});
I basically want to see if the item I am working with inside of the ForEach iteration is the last item in the dictionary. I tried
bool isLast = dictionary[ item.Key ].Equals( dictionary.Last() ) ? true : false;
but that did not work...
Dictionary.Last
returns a KeyValuePair
, and you are comparing that to just the value of a key. You'd instead need to check:
dictionary[item.Key].Equals( dictionary.Last().Value )
Also IAbstract was correct that you'd probably need to use an OrderedDictionary.
You will want to use an OrderedDictionary<TKey, TValue>
. Check MSDN ref.
With the standard Dictionary, items are not guaranteed to be persisted in any specific order.
You could test if value == dictionary.Values.Last();
Would it not be simpler to just perform the operation on the last item outside of the loop?
string requiredForSomething = dictionary.Last().Value;
You can always do this with a counter.
int itemsCount = yourDictionary.Count;
bool isLast = false;
foreach(var item in yourDictionary)
{
itemsCount--;
isLast = itemsCount == 0;
if(isLast)
{
// this is the last item no matter the order of the dictionary
}
else
{
//not the last item
}
}
Some people have mentioned to compare the value of the current item in the iteration to the last item's value, example:
dictionary[item.Key].Equals(dictionary.Last().Value)
Warning: This could result in true for any item in the dictionary if the value of the item is equal to the value of the last item in the dictionary. This is not an indicator that the item is the last item in dictionary.
Instead, if you are really trying to find if the current item in the iteration is the last item, I would suggest comparing the Key because you know it is unique, So it might look something like:
item.Key.Equals(dictionary.Last().Key)
using the System.Linq
namespace, we can do
MyDictionary[item.Key].Equals( MyDictionary.Last().Key );
the Last() method should show us, every array, dictionary, list, stack, queue the last element of it.
First, there is no ForEach
extension method for a Dictionary
or even an IEnumerable
. So you will have to fix that problem first.
Second, the Last
extension method will be painfully slow since it has to enumerate the entire collection.
Third, I am not sure it makes a whole lot of sense to do something special on the last item from a collection with an unpredictable order, but that is mostly tangential to your specific question.
Here is how I would approach the problem. Create two new extensions methods that operate on IEnumerable<T>
instances. ForEach
will be the equivalent of the List<T>.ForEach
method and WithIndex
will return another enumerator that contains the sequential index and an IsLast
flag. This is a variation of another one of my answers to a similiar problem.
dictionary.WithIndex().ForEach(
(item) =>
{
var kvp = item.Value; // This extracts the KeyValuePair
if (item.IsLast)
{
Console.WriteLine("Key=" + kvp.Key.ToString() + "; Value=" + kvp.Value.ToString());
}
});
Here are the new extension methods.
public static class ForEachHelperExtensions
{
public sealed class Item<T>
{
public int Index { get; set; }
public T Value { get; set; }
public bool IsLast { get; set; }
}
public static void ForEach<T>(this IEnumerable<T> enumerable, Action<T> action)
{
foreach (T item in enumerable)
{
action(item);
}
}
public static IEnumerable<Item<T>> WithIndex<T>(this IEnumerable<T> enumerable)
{
Item<T> item = null;
foreach (T value in enumerable)
{
Item<T> next = new Item<T>();
next.Index = 0;
next.Value = value;
next.IsLast = false;
if (item != null)
{
next.Index = item.Index + 1;
yield return item;
}
item = next;
}
if (item != null)
{
item.IsLast = true;
yield return item;
}
}
}
精彩评论