I'm trying to reverse items in a dictionary in C#.
I have tried:
Dictionary<double, int> dict = new Dictionary<double, int>();
...add itmes to it....
var v = dict.Reverse()
However, dict.Reverse() gives me a type of IEnumberable>. I was just wondering how I could make it to a type of Dictionary?
Thanks in advance.
Stop!
Dictionaries and hashtables and sets have no ordering.
There is absolutely no point in sorting or changing the order.
A Dictionary isn't an ordered data structure. For Reverse to have any real meaning you'll need to use a SortedDictionary. You can get a reversed copy of a SortedDictionary by creating a new one with a Comparer that does the opposite sorting to the original (see constructor).
var reversed = new SortedDictionary( original, new ReverseKeyComparer() );
Note that ReverseKeyComparer is a ficticious class for the example.
Also - you need to know that the SortedDictionary is somewhat of a misnomer, if you equate Dictionary to map or hashtable. It uses a binary tree implementation (Red-Black, I think) with different algorithmic complexity than the hashtable implementation of Dictionary. See the Remarks sections of their respective documentation pages. If performance is critical, you might want to consider whether the ordering is truly important.
If you want dictionaries to have a certain order, you should look into SortedDictionary.
See this article.
Related
I have code where I return a list of IWebElements and their corresponding names? My understanding is that a tuple with two items is basically the same thing but the Dictionary uses hash mapping to relate the two values. What is the advantage of using a Two Item Tuple over a Dictionary or vice versa?
public Dictionary<IWebElement, string> SelectAllOptions(IWebDriver driver, ref DataObject masterData)
{
//Get the ID of the dropdown menu
DatabaseRetrieval.GetObjectRepository(ref masterData);
var strDropMenuId = masterData.DictObjectRepository["ID"];
//Find the dropdown menu and pull all options into a list
try
{
var dropMenu = new SelectElement(driver.FindElement(By.Id(strDropMenuId)));
// TODO want to know how we want this list to return.
var options = dropMenu.Options as List<IWebElement>;
if (options != null)
{
var values = options.ToDictionary(option => option, option => option.Text);
return values;
}
}
As a general rule, you do not want to "pay" * for possibilities that your program does not need. For example, if your program is interested in retrieving and processing a sequence of pairs (also known as "two-member tuples") but it does not need to perform lookups from the first member of a tuple to the second, then providing a collection of pairs is more efficient:
IEnumerable<Tuple<IWebElement, string>> SelectAllOptions(...)
This approach takes less memory, because you do not allocate space for hash buckets
This approach takes less CPU, because there is no hash key computation or collision resolution costs
This approach does not suggest to a reader that the data is intended for lookups.
Of course if the data structure that you return is intended for lookups, then you should either return a dictionary, or construct one on the client side to transfer some of the CPU load from the server to the client.
* With memory, CPU cycles, decreased readability, etc.
A Tuple<T1, T2> represents a pair of values. That pair don't necessarily have to mean "These two items are related". When using a KeyValuePair<TKey, TValue>, you would expect that given a key, you would get a value and the two would have some sort of connection between one another.
Tuples implement IComparable and IStructuralEquatable, which makes it easier to compare Tuples.
Other than that, I would look at it from a logical perspective, do I need to match a given key to a value?, or do I just need to couple together two values and a class might be a bit of an overhead for that.
One downside of Tuples as I see it, is that you have to deal with properties labeled Item1 and Item2, which might make it a bit less readable.
Also, remember that a Tuple is a class (an Immutable one) and KeyValuePair is a struct, so when you passing them as arguments you pass Tuple by reference and KeyValuePair by value (except for explicitly declaring ref or out)
To add to the other answers, there are sometimes advantages to storing key-value data as a list of tuples instead of in a dictionary.
Depending on your needs, it might not be important that your lookups are fast, but it might be important that the order you insert into the list remains fixed. You can iterate through the keys and the values in a dictionary but the order is not defined.
Another advantage is that you can put as many pairs with the same first element into the list as you want, where with a dictionary you can only have one value per unique key.
One advantage of tuples over dictionaries is that tuples can be named.
Using List<(string text, string url)> links is more meaningful than Dictionary<string, string> links.
I need to store a list of int-string key-value pairs with a requirement to preserve the order in which items were added. Once it is initialized, it does not change, i.e. nothing added or removed..
At first I thought of using Dictionary<int,string> and everytime I need to access the items use
foreach(var entry in dict.OrderBy(e=>e.Key)) { } //as Key is `int`
However everytime ordering does not seem to be the best option to use.
Now I've come to an idea to have a List<Tuple<int, string>>, as soon as List<T> guarantees the order of items.
So, is there a better option?
Looking at the proposed possibilities:
Dictionary doesn't guarantee the order of the items
SortedDictionary sorts the items, but not in the order you added them (it sorts based on key comparison),
OrderedDictionary keeps the order, but it's not generic and would introduce unnecessary casting and boxing.
So I think you should use List<Tuple<int, string>>. It preserves order and it's good enough for iteration using foreach and indexed access. If you know the size in advance, you could use an array as well, or a read only collection type, as Cuong Le suggested in his answer.
If you allow duplicate key, List<Tuple<int, string>> would be the best choice. In order make your list as read-only, you can public read-only list after initialization:
var readonlyList = new ReadOnlyCollection<Tuple<int, string>>(yourlist);
Although Dictionary seems suitable as a data structure, it does not guarantee order of items.
List does not seem proper as it does not fit well with the data structure you are trying to store.
You may use an OrderedDictionary which guarantees the order of items.
foreach (DictionaryEntry entry in orderedDictionary)
{
//...
}
I have a dictionary structure, with multiple key value pairs inside.
myDict.Add(key1, value1);
myDict.Add(key2, value2);
myDict.Add(key3, value3);
My dictionary is used as a data source for some control. In the control's dropdown I see the items are like this:
key1
key2
key3
The order looks identical to my dictionary.
I know Dictionary is not like arrayList - you can get the index or so.
I cannot use sortedDictionary.
Now I need to add one more key value pair to this dictionary at some point of my program and I hope it has the same effect as I do this:
myDict.Add(newKey, newValue);
myDict.Add(key1, value1);
myDict.Add(key2, value2);
myDict.Add(key3, value3);
If I do this, I know newKey will display in my control as first element.
I have an idea to create a tempDict, put each pair in myDict to tempDict, then clear myDict, then add pairs back like this:
myDict.Add(newKey, newValue);
myDict.Add(key1, value1);
myDict.Add(key2, value2);
myDict.Add(key3, value3);
Is there better way than this?
Thanks!
Dictionary<K,V> does not have an ordering. Any perceived order maintenance is by chance (and an artifact of a particular implementation including, but not limited to, bucket selection order and count).
These are the approaches (just using the Base Class Libraries BCL) I know about:
Lookup<K,V>
.NET4, immutable, can map keys to multiple values (watch for duplicates during building)
OrderedDictionary
Old, non-generic, expected Dictionary performance bounds (other two approaches are O(n) for "get(key)/set(key)")
List<KeyValuePair<K,V>>
.NET2/3 okay, mutable, more legwork, can map keys to multiple values (watch for duplicates in inserts)
Happy coding.
Creating a hash data-structure that maintains insertion order is actually only a slight modification of a standard hash implementation (Ruby hashes now maintain insertion order); however, this was not done in .NET nor, more importantly, is it part of the Dictionary/IDictionary contract.
You cannot do that with the Dictionary class. It is working in your example because of a quirk in the way the data structure is implemented. The data structure actually stores the entries in temporal order in one array and then uses another array to index into the entry array. Enumerations are based on the entry array. That is why it appears to be ordered in your case. But, if you apply a series of removal and insertion operations you will notice this ordering gets perturbed.
Use KeyCollection instead. It provides O(1) retrieval by both key and index and preserves temporal ordering.
From the MSDN page on Dictionary(TKey, TValue):
For purposes of enumeration, each item in the dictionary is treated as a KeyValuePair<(Of <(TKey, TValue>)>) structure representing a value and its key. The order in which the items are returned is undefined.
I'm assuming you can't use SortedDictionary because the control depends on your data source being a Dictionary. If the control expects both the Dictionary type and sorted data, the control needs to be modified, because those two criteria contradict each other. You must use a different datatype if you need sorting/ordering functionality. Depending on undefined behavior is asking for trouble.
Don't use a dictionary - there is no guarantee the order of the keys won't change when you add further elements. Instead, define a class Pair for your Key-Value-Pairs (look here What is C# analog of C++ std::pair? for an example) and use a List<Pair> for your datasource. The List has an Insert operation you can use to insert new elements anywhere into your list.
Dictionary Should not be used to sort objects, it should rather be used to look up objects. i would suggest something else if you want to have it sort the objects too.
If you expand the Dictionary, there are no rule that would stop it from mixing up your List.
I'm looking for the fastest way to lookup if List, Set, Dictionary contains a specific Keyword (string). I don't need to store any data inside I just want to know if my Keyword is in the List.
I thought about some possibilities like:
Dictionary<string, bool> myDictionary = new Dictionary<string, bool>();
if (myDictionary.ContainsKey(valueToSearch))
{
// do something
}
but I don't need a value.
string[] myArray = {"key1", "key2", "key3"}
if (Array.IndexOf(myArray, valueToSearch) != -1)
{
// do something
}
Then I found:
List<string> list = new List<string>();
if (list.Contains(valueToSearch))
{
// do something
}
The lookup will happen very often and has to be very fast.
Any idea what's the fastest way to check if a value equals one of a given list of keys?
Of the standard collection types, Dictionary will be the fastest, since I don't think you have HashSet<T> in the compact framework. The other two do a sequential search.
In general, a Dictionary lookup is the usual solution to a problem like this, as long as your keys are good hash values that get a somewhat even distribution in the dictionary's lookup table.
However, there may be certain cases where a list lookup appears to run faster, depending on how the data is sorted and what exactly you are looking up.
The best way to tell is to run a profile of each case, and see which performs better.
I agree with Andy. You could also look at SortedList It's essentially a Dictionary that's sorted by its keys. Should make searching quicker if it's already sorted...
I have a class that inherits from a generic dictionary as follows:
Class myClass : System.Collections.Generic.Dictionary<int, Object>
I have added a list of values to this in a particular order, but I now wish to change that order. Is there any way (without removing and re-adding) that I could effectively re-index the values; so change the object at index 1 to now be at index 10 for example? For example, this doesn't work:
myClass[1].Index = 10;
Have a look at the SortedDictionary class where you can sort your items by the key.
Normally, you cannot change the index of items in Dictionary because it is against the principle ;-)
Dictionaries by themselves don't have an index order. Consider inheriting from the KeyedCollection class instead. It's a merge of a dictionary and an ordinary list, and it's designed to use a member of your items as the key, and have an index order.
Dictionaries (or more generally hashtables) do not have indicies. This goes for all languages.
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.
Taken from MSDN.
Old topic, but nevertheless the answers are not all valid
You can use Linq to achieve this.
Dictionary<int, string> Breadcrumbs = new Dictionary<int, string>();
Breadcrumbs.Add(1, "Test1");
Breadcrumbs.Add(2, "Test2");
Breadcrumbs.Add(3, "Test3");
Breadcrumbs.Add(4, "Test4");
Breadcrumbs.Add(5, "Test5");
var q = Breadcrumbs.OrderByDescending(x => x.Key);
// And bind it
gridView.DataSource = q;
gridView.DataBind();
Take a look at this question. Not a duplicate but I think it fully applies to you. They suggest you have two collections: both a dictionary (for lookups) and a List (for keeping an order that isn't sortable). If these are reference types, then you shouldn't be too concerned about memory usage here since you're only duplicating pointers (unless, of course, you have a bajillion items in here).
Dictionary<> is an unordered collection, you'll only get the elements out of it in the order you put them in by accident. You'll need a SortedDictionary<>.
I have added a list of values to this in a particular order
There is no such thing like particular order for Dictionary.
Perhaps you can look at SortedList. It supports indexing for keys and values but adding / removal are O(n) complexity vs O (log N) for SortedDictionary.