My dictionary:
Dictionary<double, string> dic = new Dictionary<double, string>();
How can I return the last element in my dictionary?
What do you mean by Last? Do you mean Last value added?
The Dictionary<TKey,TValue> class is an unordered collection. Adding and removing items can change what is considered to be the first and last element. Hence there is no way to get the Last element added.
There is an ordered dictionary class available in the form of SortedDictionary<TKey,TValue>. But this will be ordered based on comparison of the keys and not the order in which values were added.
EDIT
Several people have mentioned using the following LINQ style approach
var last = dictionary.Values.Last();
Be very wary about using this method. It will return the last value in the Values collection. This may or may not be the last value you added to the Dictionary. It's probably as likely to not be as it is to be.
Dictionaries are unordered collections - as such, there is no concept of a first or last element. If you are looking for a class that behaves like a dictionary but maintains the insertion order of items, consider using OrderedDictionary.
If you are looking for a collection that sorts the items, consider using SortedDictionary<TKey,TValue>.
If you have an existing dictionary, and you are looking for the 'last' element given some sort order, you could use linq to sort the collection, something like:
myDictionary.Values.OrderBy( x => x.Key ).Last();
By wary of using Dictionary.Keys.Last() - while the key list is sorted using the default IComparer for the type of the key, the value you get may not be the value you expect.
I know this question is too old to get any upvotes, but I didn't like any of the answers so will post my own in the hopes of offering another option to future readers.
Assuming you want the highest key value in a dictionary, not the last inserted:
The following did not work for me on .NET 4.0:
myDictionary.Values.OrderBy( x => x.Key ).Last();
I suspect the problem is that the 'x' represents a value in the dictionary, and a value has no key (the dictionary stores the key, the dictionary values do not). I may also be making a mistake in my usage of the technique.
Either way, this solution would be slow for large dictionaries, probably O(n log n) for CS folks, because it is sorting the entire dictionary just to get one entry. That's like rearranging your entire DVD collection just to find one specific movie.
var lastDicVal = dic.Values.Last();
is well established as a bad idea. In practice, this solution may return the last value added to the dictionary (not the highest key value), but in software engineering terms that is meaningless and should not be relied upon. Even if it works every time for the rest of eternity, it represents a time bomb in your code that depends on library implementation detail.
My solution is as follows:
var lastValue = dic[dic.Keys.Max()];
The Keys.max() function is much faster than sorting O(n) instead of O(n log n).
If performance is important enough that even O(n) is too slow, the last inserted key can be tracked in a separate variable used to replace dic.Keys.Max(), which will make the entire lookup as fast as it can be, or O(1).
Note: Use of double or float as a key is not best practice and can yield surprising results which are beyond the scope of this post. Read about "epsilon" in the context of float/double values.
If you're using .NET 3.5, look at:
dic.Keys.Last()
If you want a predictable order, though, use:
IDictionary<int, string> dic = new SortedDictionary<int, string>();
Instead of using:
Dictionary<double, string>
...you could use:
List<KeyValuePair<double, string>>
This would allow you to use the indexer to access the element by order instead of by key.
Consider creating a custom collection that contains a reference in the Add method of the custom collection. This would set a private field containing the last added key/value(or both) depending on your requirements.
Then have a Last() method that returns this. Here's a proof of concept class to show what I mean (please don't knock the lack of interface implementation etc- it is sample code):
public class LastDictionary<TKey, TValue>
{
private Dictionary<TKey, TValue> dict;
public LastDictionary()
{
dict = new Dictionary<TKey, TValue>();
}
public void Add(TKey key, TValue value)
{
LastKey = key;
LastValue = value;
dict.Add(key, value);
}
public TKey LastKey
{
get; private set;
}
public TValue LastValue
{
get; private set;
}
}
From the docs:
For purposes of enumeration, each item
in the dictionary is treated as a
KeyValuePair structure representing a
value and its key. The order in which
the items are returned is undefined.
So, I don't think you can rely on Dictionary to return the last element.
Use another collection. Maybe SortedDictionary ...
If you just want the value, this should work (assuming you can use LINQ):
dic.Values.Last()
You could use:
dic.Last()
But a dictionary doesn't really have a last element (the pairs inside aren't ordered in any particular way). The last item will always be the same, but it's not obvious which element it might be.
With .Net 3.5:
string lastItem = dic.Values.Last()
string lastKey = dic.Keys.Last()
...but keep in mind that a dictionary is not ordered, so you can't count on the fact that the values will remain in the same order.
A dictionary isn't meant to be accessed in order, so first, last have no meaning. Do you want the value indexed by the highest key?
Dictionary<double, string> dic = new Dictionary<double, string>();
double highest = double.MinValue;
string result = null;
foreach(double d in dic.keys)
{
if(d > highest)
{
result = dic[d];
highest = d;
}
}
Instead of using Linq like most of the other answers suggest, you can just access the last element of any Collection object via the Count property (see ICollection.Count Property for more information).
See the code here for an example of how to use count to access the final element in any Collection (including a Dictionary):
Dictionary<double, string> dic = new Dictionary<double, string>();
var lastElementIndex = dic.Count - 1;
var lastElement = dic[lastElementIndex];
Keep in mind that this returns the last VALUE, not the key.
Related
I'm trying to print out a dictionary in C# that will simulate a graph. My dictionary looks like this:
Dictionary<int, List<int>> graph = new Dictionary<int, List<int>>();
In main, I add something to the dictionary, then try to print it out:
dicOfLists myDic = new dicOfLists();
myDic.AddEdge(1, 2);
myDic.printList();
The methods AddEdge and PrintList are pretty straightforward:
AddEdge:
public void AddEdge(int v1, int v2)
{
if (graph[v1] == null)
{
graph[v1] = new List<int> { v2 };
return;
}
graph[v1].Add(v2);
}
PrintList:
for (int i = 0; i < 1; i++)
{
Console.WriteLine(graph[i][i]);
}
I haven't done much programming in C# or Python, so dictionaries are new to me. I think why I'm getting tripped up is more conceptual than anything, specifically because I'm not sure how a list works within a dictionary.
The way I currently understand it is as follows:
Upon calling Addedge(1, 2) my dictionary is creating a list with a single element 2 at position 1 of my dictionary. This is because the first parameter represents the dictionary's key, and the second represents the list. The key functions like it would in a hashtable. When the key is provided, the dictionary looks at that position, and then creates a list.
Like I said, I'm new to C# so please don't skewer me too hard. While this might be something trivial like a straightforward syntax error, I'm not able to find much of anything for this specific problem online. Any help would be greatly appreciated!
You've got one method adding key/values to a dictionary and another printing them. The method printing them doesn't "know" what's been inserted, so it's better if that method doesn't make any assumptions about what's in the dictionary. Instead of just looping through a series of possible keys (0 to 1, 0 to n, etc.) it's better to operate according to what actually is in the dictionary.
var keys = graph.Keys;
// or, if you they were entered out of sequence and you want to sort them
var keys = graph.Keys.OrderBy(k => k);
// Now you're using the actual keys that are in the dictionary, so you'll never
// try to access a missing key.
foreach(var key in keys)
{
// It's not quite as clear to me what you're doing with these objects.
// Suppose you wanted to print out everything:
Console.WriteLine($"Key: {key}");
foreach(var value in graph[key])
{
Console.WriteLine(value);
}
}
here is what I want to do.
there is a Dictionary having 54 key/value objects. I want the key/value pair at index i to be swapped with the key/value pair at index j...
int i=1; int j=3;
Dictionary<String, int> theDeck = new Dictionary<String, int>();
theDeck.Add("zero", 0);
theDeck.Add("one", 1);
theDeck.Add("two", 2);
theDeck.Add("three", 3);
KeyValuePair<String, int> p1 = theDeck.ElementAt(i);
KeyValuePair<String, int> p2 = theDeck.ElementAt(j);
theDeck.ElementAt(i) = p2; //THIS LINE DOES NOT WORK. WHAT IS ITS ALTERNATIVE
theDeck.ElementAt(j) = p1; //THIS LINE DOES NOT WORK. WHAT IS ITS ALTERNATIVE
Dictionary<,> instances don't have "indexes" - you shouldn't treat them as ordered at all. Any order you may happen to notice when iterating over entries should be seen as an implementation detail.
If you want a specific order, there are various different types you could use, depending on your requirements. For example, to sort based on the key you'd use SortedDictionary<,> or SortedList<,>. For arbitrary ordering, consider OrderedDictionary (which is unfortunately non-generic).
Do you definitely need a dictionary at all? Could you just use a List<KeyValuePair<string, int>> or perhaps a List<Card> where Card is a custom type? (I'm guessing at your use case - Card could be any type which represents everything in your entry.)
Make mirroring (the 2nd) dictionary, and use it as a key source. Combine in 3d dictionary, while processing.
Try this.This worked for me.
First convert dictionary to list then find indexes of objects to be swapped.After swapping convert list back to dictionary.
var list = someDictionary.ToList();
int indexA = list.FindIndex(objA=> (condition));
int indexB = list.FindIndex(objB => (condition));
list.SwapListEntries(indexA, indexB);
someDictionary=list.ToDictionary(obj => obj.Key, obj => obj.Value);
I Have a Hashtable that I dont know What is the content of .
now I want to get one Key and value from it;
I use hashtable because of its speed because content of hashtable is over 4,500,000 KeyValuePair so I cant use GetEnumerator its reduce program speed
You use a List<TKey>:
Dictionary<string, string> dict = ... your hashtable which could be huge
List<string> keys = new List<string>(dict.Keys);
int size = dict.Count;
Random rand = new Random();
string randomKey = keys[rand.Next(size)];
We are just creating a List<TKey> whose elements are pointing to the same location in memory as the keys of your hashtable and then we pick a random element from this list.
And if you want to get a random element value from the hashtable, this should be pretty straightforward given a random key.
string randomeElement = dict[randomKey];
I cant use GetEnumerator its reduce program speed"
Well that's a problem. You've accepted an answer which does iterate over all the entries, and also copies the keys into a new list, so it's not clear whether you've abandoned that requirement.
An approach which will certainly be more efficient in memory and potentially in speed as well is to iterate over the whole dictionary, but retaining a random element at any one time, with an optimization for collections where we can obtain the count cheaply. Here's an extension method which will do that for any generic sequence in .NET:
public static T RandomElement<T>(this IEnumerable<T> source,
Random rng)
{
// Optimize for the "known count" case.
ICollection<T> collection = source as ICollection<T>;
if (collection != null)
{
// ElementAt will optimize further for the IList<T> case
return source.ElementAt(rng.Next(collection.Count));
}
T current = default(T);
int count = 0;
foreach (T element in source)
{
count++;
if (rng.Next(count) == 0)
{
current = element;
}
}
if (count == 0)
{
throw new InvalidOperationException("Sequence was empty");
}
return current;
}
So for a Dictionary<TKey, TValue> you'd end up with a KeyValuePair<TKey, TValue> that way - or you could project to Keys first:
var key = dictionary.Keys.RandomElement(rng);
(See my article on Random for gotchas around that side of things.)
I don't believe you'll be able to do any better than O(n) if you want a genuinely pseudo-random key, rather than just an arbitrary key (which you could get by taking the first one in the sequence, as stated elsewhere).
Note that copying the keys to a list as in Darin's answer allows you to get multiple random elements more efficiently, of course. It all depends on your requirements.
How random does the random key have to be?
Hash tables don't define an order for their items to be stored in, so you could just grab the first item. It's not really random, but it's not insertion order or sorted order either. Would that be random enough?
Dictionary<string, string> dict = GetYourHugeHashTable();
KeyValuePair<string, string> randomItem = dict.First();
DoAComputation(randomItem.Key, randomItem.Value);
dict.Remove(randomItem.Key);
with Linq you can do:
Dictionary<string, string> dicto = new Dictionary<string, string>();
Random rand = new Random();
int size = dicto.Count;
int randNum = rand.Next(0, size);
KeyValuePair<string, string> randomPair = dicto.ElementAt( randNum );
string randomVal = randomPair.Value;
For instance,
string tmp = dicto.ElementAt( 30 ).Value;
Would copy the value of the thirtieth item in the Dicto to the string tmp.
Internally, I think it walks through the keypairs one at a time, till it gets to the thirtieth, instead of copying them all, so you don't need to load all the elements into memory.
I'm not sure what you meant by not knowing what the content is.
You don't know the types in the KeyValuePair of the dicto?
Or just don't know what values will be in the dicto?
Hashtable.Keys will give you a pointer to the internal list of keys. That is speedy. Also removing an item from a Hashtable is an O(1) operation, so this will also be speedy, even with large amounts of items.
You could do a loop like this (I see no reason to use random in your question);
var k = Hashtable.Keys(); // Will reflect actual contents, even if changes occur
while (k.Count > 0 )
{
var i = Keys.First();
{
Process(i);
Hashtable.Remove(i)
}
}
Well, if you know which version of the .NET BCL you'll be targeting (i.e., if it's fixed), you could always plumb the internals of Dictionary<TKey, TValue> to figure out how it stores its keys privately and use that to pluck a random one.
For example, using the version of Mono I currently have installed on my work laptop, I see that the Dictionary<TKey, TValue> type has a private field called keySlots (I assume this will be different for you if you're on Windows). Using this knowledge you could implement a function looking something like this:
static readonly Dictionary<Type, FieldInfo> KeySlotsFields = new Dictionary<Type, FieldInfo>();
public static KeyValuePair<TKey, TValue> GetRandomKeyValuePair<TKey, TValue>(this Random random, Dictionary<TKey, TValue> dictionary, Random random = null)
{
// Here's where you'd get the FieldInfo that you've identified
// for your target version of the BCL.
FieldInfo keySlotsField = GetKeySlotsField<TKey, TValue>();
var keySlots = (TKey[])keySlotsField.GetValue(dictionary);
var key = (TKey)keySlots[random.Next(keySlots.Length)];
// The keySlots field references an array with some empty slots,
// so we need to loop until we come across an existing key.
while (key == null)
{
key = (TKey)keySlots[random.Next(keySlots.Length)];
}
return new KeyValuePair<TKey, TValue>(key, dictionary[key]);
}
// This happens to work for me on Mono; you'd almost certainly need to
// rewrite it for different platforms.
public FieldInfo GetKeySlotsField<TKey, TValue>()
{
Type keyType = typeof(TKey);
FieldInfo keySlotsField;
if (!KeySlotsFields.TryGetValue(keyType, out keySlotsField))
{
KeySlotsFields[keyType] = keySlotsField = typeof(Dictionary<TKey, TValue>).GetField("keySlots", BindingFlags.Instance | BindingFlags.NonPublic);
}
return keySlotsField;
}
This could be an appropriate solution in your case, or it could be a horrible idea. Only you have enough context to make that call.
As for the example method above: I personally like adding extension methods to the Random class for any functionality involving randomness. That's just my choice; obviously you could go a different route.
I am having a dictionary which was defined as follows
Dictionary<int, List<int>> dict1 = new Dictionary<int, List<int>>();
I will have a list element where i can store the values which will come from database
List<int> lstdbTaskID = new List<int>();
assume this holds
100 105 110 200
respectively.
I will have my dictionary with values stored as follows. Assume that i have 2 keys 10,20 respectively, and for this key values i will have my values as for 10 i will have 100,105 and 110 and for 20 i will have 200.
I would like to compare these values with the list available lstdbTaskID
I tried this
foreach (int strlst in lstdbTaskID)
{
if (dict1.ContainsValue(lstdbTaskID[strlst]))
}
But i am getting errors as follows
The best overloaded method match for 'System.Collections.Generic.Dictionary>.ContainsValue(System.Collections.Generic.List)' has some invalid arguments`
and
Cannot convert from 'int' to 'System.Collections.Generic.List'`
can any help me on this?
Your code is wrong at because you are trying to compare int value with List of int.
Your dictionary is:
Dictionary of int to List of int.
and you have another structure as
List of int
so when you do:
// Compiler fails here because you are trying to check whether dictionary contains
// the given integer value. Dictionary in this case has a list of integers as its `Value`
// in its `<Key,Value>` pair.
dict1.ContainsValue(lstdbTaskID[strlst])
Use linq statement:
foreach (int strlst in lstdbTaskID)
{
if (dict1.Any(pair => pair.Value.Contains(strlst)))
{
// do something
}
}
Edit: If you want this without linq, do the linq task by self.
foreach (int strlst in lstdbTaskID)
{
foreach (int key in dict1.Keys)
{
if (dict1[key].Contains(strlst))
{
// do something
}
}
}
Look at the type of the value you're storing in your dictionary - it's a List<int>, not an int. So it makes no sense to ask whether the dictionary contains a value of 5, say.
However, it does make sense to ask if the dictionary contains any value (list) which itself contains 5.
For example:
foreach (int strlst in lstdbTaskID)
{
if (dict1.Values.Any(list => list.Contains(strlst))
{
...
}
}
However, that's really not a very efficient way of representing it. It's not clear what the best of representing it is though, without knowing what you're going to do with the results. You may just want a HashSet<int> containing all the values from all the lists, for example - but if you want to get back to the keys whose values contained a particular ID, that's a different matter.
EDIT: In .NET 2.0 land, you could use:
foreach (int strlst in lstdbTaskID)
{
foreach (List<int> list in dict1.Values)
{
if (list.Contains(strlst))
}
}
... but you're really not using the dictionary as a dictionary in either case here...
I am having slight problems understanding your question fully, however, my answer should push you in the right direction. Seeing as you do not have access to Linq (as you are using .Net 2.0):
static bool IsContained(IEnumerable<int> lstdbTaskID, Dictionary<int, HashSet<int>> dict1)
{
foreach (int strlst in lstdbTaskID)
foreach (HashSet<int> value in dict1.Values)
if (value != null && value.Contains(strlst))
return true;
return false;
}
You should use a HashSet<int> as it is far faster for looking up values (and is supported in .Net 2.0); however, you should not use HashSet<int> (and instead use List<int>) if:
The list needs to store duplicates.
- or - The order of the values is important.
Well, dict1 is a dictionary of dictionaries, not ints. So dict1.ContainsValue takes a dictionary as a parameter - you're checking whether it contains a given dictionary or not. But you're giving it an int.
Try this:
if (dict1.Any(x => x.Value.ContainsValue(strlst))) // ...
What is the difference in Dictionary.add(key, value) and Dictionary[key] = value?
I've noticed that the last version does not throw an ArgumentException when inserting a duplicate key, but is there any reason to prefer the first version?
Edit: Does anyone have an authoritative source of information about this? I've tried MSDN, but it is as always a wild goose chase :(
The performance is almost a 100% identical. You can check this out by opening the class in Reflector.net
This is the This indexer:
public TValue this[TKey key]
{
get
{
int index = this.FindEntry(key);
if (index >= 0)
{
return this.entries[index].value;
}
ThrowHelper.ThrowKeyNotFoundException();
return default(TValue);
}
set
{
this.Insert(key, value, false);
}
}
And this is the Add method:
public void Add(TKey key, TValue value)
{
this.Insert(key, value, true);
}
I won't post the entire Insert method as it's rather long, however the method declaration is this:
private void Insert(TKey key, TValue value, bool add)
And further down in the function, this happens:
if ((this.entries[i].hashCode == num) && this.comparer.Equals(this.entries[i].key, key))
{
if (add)
{
ThrowHelper.ThrowArgumentException(ExceptionResource.Argument_AddingDuplicate);
}
Which checks if the key already exists, and if it does and the parameter add is true, it throws the exception.
So for all purposes and intents the performance is the same.
Like a few other mentions, it's all about whether you need the check, for attempts at adding the same key twice.
Sorry for the lengthy post, I hope it's okay.
The first version will add a new KeyValuePair to the dictionary, throwing if key is already in the dictionary. The second, using the indexer, will add a new pair if the key doesn't exist, but overwrite the value of the key if it already exists in the dictionary.
IDictionary<string, string> strings = new Dictionary<string, string>();
strings["foo"] = "bar"; //strings["foo"] == "bar"
strings["foo"] = string.Empty; //strings["foo"] == string.empty
strings.Add("foo", "bar"); //throws
To answer the question first we need to take a look at the purpose of a dictionary and underlying technology.
Dictionary is the list of KeyValuePair<Tkey, Tvalue> where each value is represented by its unique key. Let's say we have a list of your favorite foods. Each value (food name) is represented by its unique key (a position = how much you like this food).
Example code:
Dictionary<int, string> myDietFavorites = new Dictionary<int, string>()
{
{ 1, "Burger"},
{ 2, "Fries"},
{ 3, "Donuts"}
};
Let's say you want to stay healthy, you've changed your mind and you want to replace your favorite "Burger" with salad. Your list is still a list of your favorites, you won't change the nature of the list. Your favorite will remain number one on the list, only it's value will change. This is when you call this:
/*your key stays 1, you only replace the value assigned to this key
you alter existing record in your dictionary*/
myDietFavorites[1] = "Salad";
But don't forget you're the programmer, and from now on you finishes your sentences with ; you refuse to use emojis because they would throw compilation error and all list of favorites is 0 index based.
Your diet changed too! So you alter your list again:
/*you don't want to replace Salad, you want to add this new fancy 0
position to your list. It wasn't there before so you can either define it*/
myDietFavorites[0] = "Pizza";
/*or Add it*/
myDietFavorites.Add(0, "Pizza");
There are two possibilities with defining, you either want to give a new definition for something not existent before or you want to change definition which already exists.
Add method allows you to add a record but only under one condition: key for this definition may not exist in your dictionary.
Now we are going to look under the hood. When you are making a dictionary your compiler make a reservation for the bucket (spaces in memory to store your records). Bucket don't store keys in the way you define them. Each key is hashed before going to the bucket (defined by Microsoft), worth mention that value part stays unchanged.
I'll use the CRC32 hashing algorithm to simplify my example. When you defining:
myDietFavorites[0] = "Pizza";
What is going to the bucket is db2dc565 "Pizza" (simplified).
When you alter the value in with:
myDietFavorites[0] = "Spaghetti";
You hash your 0 which is again db2dc565 then you look up this value in your bucket to find if it's there. If it's there you simply rewrite the value assigned to the key. If it's not there you'll place your value in the bucket.
When you calling Add function on your dictionary like:
myDietFavorite.Add(0, "Chocolate");
You hash your 0 to compare it's value to ones in the bucket. You may place it in the bucket only if it's not there.
It's crucial to know how it works especially if you work with dictionaries of string or char type of key. It's case sensitive because of undergoing hashing. So for example "name" != "Name". Let's use our CRC32 to depict this.
Value for "name" is: e04112b1
Value for "Name" is: 1107fb5b
Dictionary.Add(key, value) and Dictionary[key] = value have different purposes:
Use the Add method to add new key/value pair, existing keys will not be replaced (an ArgumentException is thrown).
Use the indexer if you don't care whether the key already exists in the dictionary, in other words: add the key/value pair if the the key is not in the dictionary or replace the value for the specified key if the key is already in the dictionary.
Yes, that is the difference, the Add method throws an exception if the key already exists.
The reason to use the Add method is exactly this. If the dictionary is not supposed to contain the key already, you usually want the exception so that you are made aware of the problem.
To insert the Value into the Dictionary
Dictionary<string, string> dDS1 = new Dictionary<string, string>();//Declaration
dDS1.Add("VEqpt", "aaaa");//adding key and value into the dictionary
string Count = dDS1["VEqpt"];//assigning the value of dictionary key to Count variable
dDS1["VEqpt"] = Count + "bbbb";//assigning the value to key
Given the, most than probable similarities in performance, use whatever feel more correct and readable to the piece of code you're using.
I feel an operation that describes an addition, being the presence of the key already a really rare exception is best represented with the add. Semantically it makes more sense.
The dict[key] = value represents better a substitution. If I see that code I half expect the key to already be in the dictionary anyway.
One is assigning a value while the other is adding to the Dictionary a new Key and Value.