I'm using a Dictionary<char, ulong> where the char is a obj no, & ulong is offset.
Now, I need to access the Keys of Dictionary. Keys is any random number which cant predict.
I am using VS-2005.
I am new to C# so plz provide some code.
As Matt says, the Keys property is your friend. This returns a KeyCollection, but usually you just want to iterate over it:
foreach (char key in dictionary.Keys)
{
// Whatever
}
Note that the order in which the keys are returned is not guaranteed. In many cases it will actually be insertion order, but you must not rely on that.
I'm slightly concerned that you talk about the keys being random numbers when it looks like they're characters. Have you definitely chosen the right types here?
One more tip - if you will sometimes need the values as well as the keys, you can iterate over the KeyValuePairs in the dictionary too:
foreach(KeyValuePair<char, ulong> pair in dictionary)
{
char c = pair.Key;
ulong x = pair.Value;
...
}
Dictionary provides a Keys property that contains all of the keys in the dictionary.
Related
Let's say that I have a ConcurrentDictionary:
var dict = new ConcurrentDictionary<string, someObject>();
dict.TryAdd("0_someA_someB_someC", obj0);
dict.TryAdd("1_someA_someB_someC", obj1);
dict.TryAdd("2_someA_someB_someC", obj2);
dict.TryAdd("3_someA_someB_someC", obj3);
The <number>_ in the keys is incremented and being a dictionary, there is no guarantee that the elements are in order.
Now, imagine I wanted to remove all items from the dictionary that have the number less than 2. I have no idea what the keys will look like, only that they will be prefixed with a number as above.
How can I remove all elements from the dictionary who's key starts with a value less than 2?
For example, the resulting dict after this process will look like this:
dict.TryAdd("2_someA_someB_someC", obj2);
dict.TryAdd("3_someA_someB_someC", obj3);
Presuming it has always this format, you can use LINQ:
var keysToRemove = dict.Keys.Where(key => int.Parse(key.Remove(key.IndexOf('_'))) < 2).ToList();
keysToRemove.ForEach(key => dict.TryRemove(key, out someObject obj));
String.Remove removes the part starting from _ and then parses the remaiming first part, the number. It will only select the keys which number is lower than 2.
This list will be used to remove the items from the dictionary. Of course you need a lock to make this thread-safe.
Parse the number that comes before the first underscore (Tip: IndexOf and Substring)
Convert it to integer (Tip: int.TryParse)
Compare number to the value (2 in this case)
Filter the keys applying this method, store them in a collection. Iterate over the collection and call TryRemove method to remove entries associated with the key.
You would need to iterate across the dictionary collecting the keys that match the criteria and then iterate across that list of keys deleting from the dictionary. A for-each across a dictionary returns items with Key and Value properties, so you can examine the Key property to decide whether or not to delete. You cannot delete in the same loop as this will result in an error.
You could use Split to split the key into an array on the _ character, convert the first item in the resulting array into an int (note this will throw if the key doesn't start with an int), and if it's less than 2, remove it from the dictionary:
foreach (var item in dict.Where(kvp => int.Parse(kvp.Key.Split('_')[0]) < 2))
{
SomeObject tempObject;
dict.TryRemove(item.Key, out tempObject);
}
I started reading C# in depth. Now I'm in the journey of Generics. I came across the first example of Generics in this book as:
static Dictionary<string,int> CountWords(string text)
{
Dictionary<string,int> frequencies;
frequencies = new Dictionary<string,int>();
... //other code goes here..
And after this code, author says that:
The CountWords method first creates an empty map from string to int
This looks vague to me, as a novice in C#, what the author is trying to mean string to int(in the above statement)? I'm bit confused with this line.
Thanks in advance.
Lets say we want to count the words in a paragraph:
I started reading C# in depth. Now I am in the journey of Generics.
I came across the first example of Generics in this book as
In order to count the words, you'll need some data structure that will be able to store a number of occurrences for each of the words, that will basically attach a number to a string, like
I - 3 times
in - 3 times
Generics - 2 times
etc...
that structure maps a string to an integer, and in C# Generics, that structure is a Dictionary<string,int>
BTW, if you are a C# beginner, i would recommend against C# in depth, which, while being a great book, assumes a quite advanced reader.
He means that string is your key and int is the value paired with the key.
Dictionary<string,int> maps a string key (or lookup) to an int value.
Consider Dictionary<string,int> frequencies.
When you try to add an item you use (for example)
frequencies.Add("key3", 3)
When you add another item you cannot repeat "key3", because in Dictionary that's a unique key; so you create a "map" because you are sure you have unique keys and you can recall values using their key: frequencies["key3"]...
Dictionary<string, int> frequencies = new Dictionary<string, int>();
frequencies.Add("key3", 3);
frequencies.Add("key4", 4);
frequencies.Add("key3", 5); // This raises an error
int value = frequencies["key3"];
This function counts all words in a given string. In the returned dictionary exist for every found word one entry with the word as key. In the int value is stored, how many times this word was found in the string.
It means from the Key to the Value
I don't think I posted enough detail in the previous question and people seemed to stop responding so I'm reposting as we need to know why this problem is happening
I'm working with a SortedDictionary and when we loop through it we get odd results.
there is a lot of nesting involved and the final dictionary is actually the child of another dictionary which is the child of another!
is the the complete nest.
SortedDictionary<String, SortedDictionary<String, SortedDictionary<int, SortedDictionary<String, String>>>>()
The dictionary i'm looping through is
SortedDictionary<int, SortedDictionary<String, String>>
And Here is the loop:
foreach (SortedDictionary<String, String> cDic in openTrades.Values)
{
String cTimestamp = convertTimestamp(cDic["open"]);
if (!closeTrades.ContainsKey(cDic["key"]) && barArray.ContainsKey(cDic["pair"]))
{
foreach (SortedDictionary<String, String> bDic in barArray[cDic["pair"]][cDic["frame"]].Values)
{
//This is the relative Loop
}
}
}
barArray is our Primary SortedDictionary (the subject of this question)
openTrades is another SortedDictionary
Now when we loop through the dictionary with an integer as an index we get varied results - IE. if we have 1,2,3,4 as the keys when looping through it may present them in this order: 4,2,1,3 which clearly doesn't make sense as this is meant to be a sorted dictionary.
Any help as quickly as possible would be greatly appreciated as im stumped on this issue.
Thanks
James
My gut feeling is that you are misinterpreting the results that you are seeing. In the loop that you show, you are not looping through the int key, you are looping through the list of values. Thus, you have no way to determine in which order the int keys are actually returned.
You probably have something in the SortedDictionary itself, that should indicate which int from the enclosing dictionary it belongs to. I would imagine, that there is some bug in how you are forming these values, so that the int in the key does not actually match the value.
I suggest to narrow the issue down, that you foreach through openTrades and not openTrades.Values. This way you'll be able to see the real keys in the returned KeyValuePair. I'm pretty sure they will appear sorted.
I have a known-good Dictionary, and at run time I need to create a new Dictionary and run a check to see if it has the same key-value pairs as the known-good Dictionary (potentially inserted in different orders), and take one path if it does and another if it doesn't. I don't necessarily need to serialize the entire known-good Dictionary (I could use a hash, for example), but I need some on-disk data that has enough information about the known-good Dictionary to allow for comparison, if not for recreation. What is the quickest way to do this? I can use a SortedDictionary, but the amount of time required to initialize and add values counts in the speed of this task.
Concrete example:
Consider a Dictionary<String,List<String>> that looks something like this (in no particular order, obviously):
{ {"key1", {"value1", "value2"} }, {"key2", {"value3", "value4"} } }
I create that Dictionary once and save some form of information about it on disk (a full serialization, a hash, whatever). Then, at runtime, I do the following:
Dictionary<String,List<String>> d1 = new Dictionary<String,List<String>> ();
Dictionary<String,List<String>> d2 = new Dictionary<String,List<String>> ();
Dictionary<String,List<String>> d3 = new Dictionary<String,List<String>> ();
String key11 = "key1";
String key12 = "key1";
String key13 = "key1";
String key21 = "key2";
String key22 = "key2";
String key23 = "key2";
List<String> value11 = new List<String> {"value1", "value2"};
List<String> value12 = new List<String> {"value1", "value2"};
List<String> value13 = new List<String> {"value1", "value2"};
List<String> value21 = new List<String> {"value3", "value4"};
List<String> value22 = new List<String> {"value3", "value4"};
List<String> value23 = new List<String> {"value3", "value5"};
dict1.add(key11, value11);
dict1.add(key21, value21);
dict2.add(key22, value22);
dict2.add(key12, value12);
dict3.add(key13, value13);
dict3.add(key23, value23);
dict1.compare(fileName); //Should return true
dict2.compare(fileName); //Should return true
dict3.compare(fileName); //Should return false
Again, if the overall time from startup to the return from compare() is quicker, I can change this code to use a SortedDictionary (or anything else) instead, but I can't guarantee ordering and I need some consistent comparison. compare() could load a serialization and iterate through the dictionaries, it could serialize the in-memory dictionary and compare the serialization to the file name, or it could do any number of other things.
Solution one: use set equality.
If the dictionaries are of different sizes, you know they are unequal.
If they are of the same size then build a mutable hash set of keys from one dictionary. Remove from it all the keys from the other dictionary. If you attempted to remove a key that wasn't there, then the key sets are unequal and you know which key was the problem.
Alternatively, build two hash sets and take their intersection; the resulting intersection should be the size of the original sets.
This takes O(n) time and O(n) space.
Once you know that the key sets are equal then go through all the keys one at a time, fetch the values, and do comparison of the values. Since the values are sequences, use SequenceEquals. This takes O(n) time and O(1) space.
Solution two: sort the keys
Again, if the dictionaries are of different size, you know they are unequal.
If they are of the same size, sort both sets of keys and do a SequenceEquals on them; if the sequences of keys are unequal then the dictionaries are unequal.
This takes O(n lg n) time and O(n) space.
If that succeeds, then again, go through the keys one at a time and compare the values.
Solution three:
Again, check the dictionaries to see if they are the same size.
If they are, then iterate over the keys of one dictionary and check to see if the key exists in the other dictionary. If it does not, then they are not equal. If it does, then check the corresponding values for equality.
This is O(n) in time and O(1) in space.
How to choose amongst these possible solutions? It depends on what the likely failure mode is, and whether you need to know what the missing or extra key is. If the likely failure mode is a bad key then it might be more performant to choose a solution that concentrates on finding the bad key first, and only checking for bad values if all the keys turn out to be OK. If the likely failure mode is a bad value, then the third solution is probably best, since it prioritizes checking values early.
Due to my comments on the accepted answer, here's a stricter check.
goodDictionary.Keys.All(k=>
{
List<string> otherVal;
if(!testDictionary.TryGetValue(k,out otherVal))
{
return false;
}
return goodDictionary[k].SequenceEquals(otherVal);
})
If you already have serialisation, then take the hash (I recommend SHA-1) of each serialised dictionary and then compare them.
I don't think there is a magic bullet here; you just need to do a lookup for each key pair:
public bool IsDictionaryAMatch(Dictionary<string, List<string>> dictionaryToCheck)
{
foreach(var kvp in dictionaryToCheck)
{
// Do the Keys Match
if(!goodDictionary.Exists(x => x.Key == kvp.Key))
return false;
foreach(var valueElement in kvp.Value)
{
// Do the Values in each list match
if(!goodDictionary[kvp.Key].Exists(x => x == valueElement))
return false;
}
}
return true;
}
Well, at some point you need to compare that each key has the same value, but before that you can do quick things, like checking to see how many keys each dictionary has, then checking that the list of keys match. Those should be fairly quick, and if either of those tests fail you can abort the more expensive testing.
After that, you might be able to build separate lists of keys and then fire off a Paraells query to compare the actual values.
I am currently developing a program that uses C#'s Dictionary container (specifically, SortedDictionary). This container works very well for my purposes except for one specific case because I want random access. Specifically, I am generating a random position using a pseudorandom number generator and I need to be able to access that value in the SortedDictionary. At the point that this happens, I do not have a key value.
I could potentially switch to a List which would solve this problem, but would create problems in the rest of the algorithm where SortedDictionary works quite well. Any suggestions/solutions would be much appreciated.
I am currently developing Visual Studio 2005.
Thank you.
You can use a SortedList and it has a Values collection which you may access through an integer index.
public TValue GetRandomElement<TKey, TValue>(SortedDictionary<TKey, TValue> dict)
{
Random randGen = new Random();
int randIndex = randGen.Next(dict.Values.Count);
int i = 0;
foreach (TValue value in dict.Values)
{
if (i++ == randIndex)
return value;
}
// this shouldn't happen unless I have a bug above or you are accessing the dictionary from multiple threads
return default(TValue);
}
Blindly enumerating the ValueCollection is not the most efficient thing in the world. But it gets the job done. If this is a frequent operation in your scenario, you should consider a hybrid data structure that has the performance characteristics needed for both dictionary lookup and random access.
Linq could do this for you:
int n = GetRandomIndex();
object item = dictionary.ElementAt(n).Value;
You don't provide enough information to come up with a solution. How many elements, how often are you going to do this, do you have memory/speed constraints? BTree, SortedList, inserting special nodes in the SortedDictionary could all be useful
Will pulling a random key work?
var randValue = myDictionary.Values.ToList()[myRandomInt];
Edit:
Seems the keys collection and values collection are both IEnumerables so you can't use [] operators. This is the best it gets it seems.
Edit:
Without Linq... Perhaps expensive, but you could copyto array and then pull a value at an index
System.Collections.Generic.KeyValuePair<string, int>[] dictCopy = new System.Collections.Generic.KeyValuePair<string, int>[myDictionary.Count];
myDictionary.CopyTo(dictCopy, 0);
var randValue = dictCopy[myRandomInt].Value;