Check a Hashtables key/value pairs for a combination in C#? - c#

I have a Hashtable, which contains values like this:
key: 123456 value: UV
key: 654321 value: HV
...
Now I want to check if a combination already exists and dont insert anything. So if my key is 123456 and my value is UV, no new entry is added. How could I do this?
Thanks :-)

A Hashtable (or, preferably, a Dictionary<TKey, TValue>) contains exactly one value for a stored key. So, if you add a new key-value-pair to the collection, you can simply check for the existence of the key before doing so:
static bool AddIfNotContainsKey<K,V>(this Dictionary<K,V> dict, K key, V value)
{
if (!dict.ContainsKey(key))
{
dict.Add(key, value);
return true;
}
return false;
}
Example:
var dict = new Dictionary<string, string>();
dict.AddIfNotContainsKey("123456", "UV"); // returns true
dict.AddIfNotContainsKey("654321", "HV"); // returns true
dict.AddIfNotContainsKey("123456", "??"); // returns false
string result = dict["123456"]; // result == "UV"

Use the Contains method of the Hashtable, and as #dtb says the Hashtable contains one value for a key, so in your case if you need to have things like ("key1","value1"), ("key1","value2") then maybe is more apropiate store the pair as the key making the existence of this values perfectly valid.

you could make a function with something like this, I have tried it and it is working.
class Program
{
static void Main()
{
Dictionary<string, bool> d = new Dictionary<string, bool>();
d.Add("cat", true);
d.Add("dog", false);
d.Add("sprout", true);
// A.
// We could use ContainsKey.
if (d.ContainsKey("dog"))
{
// Will be 'False'
bool result = d["dog"];
Console.WriteLine(result);
}
// B.
// Or we could use TryGetValue.
bool value;
if (d.TryGetValue("dog", out value))
{
// Will be 'False'
bool result = value;
Console.WriteLine(result);
}
}
}

Related

How to return only only specified Key's value from dictionary using TryGetValue() method

I am trying to get my method to return a matchKey's value as I pass this to the method but the value is returning as Null. Also it shows my dictionary contains the Key and the value i am looking for also my if(Items.TryGetValue(item.Key.Contains(matchKey).ToString() returns true but it does not add it to the second dictionary I have.. My Items dictionary has all the key and values and I am able to return that.. but I am trying to extract one of the key which is "id" and its value "80" from that and adding to my second dictionary keyValues and returning that if it contains..
Here is the Json after Serializing
{"UserId":"","UserId2":"","id":"80"}
public Dictionary<string, string> GetKeyAndValues(string matchKey)
{
string data = JsonConvert.SerializeObject(dataEntries);
Dictionary<string, string> Items = JsonConvert.DeserializeObject<Dictionary<string, string>>(data);
Dictionary<string, string> keyValues = new Dictionary<string, string>();
foreach (KeyValuePair<string, string> item in Items)
{
if (!Items.ContainsKey(item.Key))
{
Items.Add(item.Key.ToString(), item.Value.ToString());
}
var value = Items[matchKey];
if(Items.TryGetValue(item.Key.Contains(matchKey).ToString(), out value))
{
keyValues.Add(matchKey, value);
return keyValues;
}
}
return Items;
}
The major problem in your code is in this line of code:
if (Items.TryGetValue(item.Key.Contains(matchKey).ToString(), out value))
It doesn't check if an item with the key matchKey is contained in the Items dictionary. This sub-expression item.Key.Contains(matchKey) checks if matchKey is contained in the Items and returns true or false. Therefore this problem line checks if a key with value true of false is contained in the Items.
Here is a fixed method GetKeyAndValues:
public static Dictionary<string, string> GetKeyAndValues(string matchKey)
{
string data = JsonConvert.SerializeObject(dataEntries);
Dictionary<string, string> Items = JsonConvert.DeserializeObject<Dictionary<string, string>>(data);
// We don't need a loop to check if a key "matchKey" is contained in the "Items".
// Items.TryGetValue(matchKey, out string value) checks if "matchKey" is contained
// in the "Items", and if it is contained it returns an appropriate "value".
if (Items.TryGetValue(matchKey, out string value))
{
// Here we create a Dictionary with a single pair (matchKey, value).
return new Dictionary<string, string> {{matchKey, value}};
}
return Items;
}
Here is a useful link to the documentation of the method Dictionary.TryGetValue.

Why does comparing each of C# Dictionary Key/Value pair gives different result, than comparing Dictionary Keys and Values done at once?

I've currently had to put some data in dictionary, to check whether some of the actual data, match the expected one for some of my tests.
For the task I've created a Dictionary that looked somehow like that:
Dictionary<string, string> dict = new Dictionary<string, string>(){
{a, a},
{b, b},
{c, c}
};
The first that I've tried was to compare the Dictionary Values and Keys in conditional statement like shown below and I was kinda suprised with the false result of this conditional statement:
if(dict.Keys.Equals(dict.Values)) {
///// received false as a result here //////
}
When I then tried the next approach which was to iterate through all of dictionary items and to compare each of their Value Key pairs, it suddenly resulted in giving me the expected (true) result for all items of Dictionary:
foreach (var item in dict) {
if (item.Key.Equals(item.Value))
{
///// received true as a result /////
}
else { other code here }
}
Why did I get the false result for the first approach described?
You expect them both to be an ICollection if you look into the docs.
Have a look in the reference source of the dictionary class.
The Keys and Values Properties are implemented using different collection-types.
// Line 135
public KeyCollection Keys {
get {
Contract.Ensures(Contract.Result<KeyCollection>() != null);
if (keys == null) keys = new KeyCollection(this);
return keys;
}
}
// Line 157
public ValueCollection Values {
get {
Contract.Ensures(Contract.Result<ValueCollection>() != null);
if (values == null) values = new ValueCollection(this);
return values;
}
}
Also if you look into the KeyCollection and ValueCollection Classes, you will notice, that there is no other implementation of the Equals() Method. As those classes don't derive from any other class, you may be sure that dict.Keys.Equals(dict.Values) will call the object.Equals() Method.
This call will obviously return false.

C# How do you loop through multiple dictionaries?

A standard dictionary would look like this:
public Dictionary<int, DictionarySetup> H = new Dictionary<int, DictionarySetup>()
{
{18000, new DictionarySetup { Some values }},
};
Ranging from A-T, all of these are in a class called DictionaryInit, right now I check the value if there's a match with this boolean:
public Boolean Dictionary_Test(Dictionary<int, DictionarySetup> AccountLexicon)
{
DictionarySetup ClassValues;
if (AccountLexicon.TryGetValue(MapKey, out ClassValues))
{
return true;
}
return false;
}
Now, I'm looking for a more efficient method to loop through each Dictionary and, if there's a match, get that particular dictionary for use in a subsequent method, this is what it looks like now in an if/else:
if(Dictionary_Test(theDictionary.C) == true)
{
Dictionary_Find(Account_String, rowindex, theBSDictionary.C, Cash_Value, txtCurrency.Text);
}
else if (Dictionary_Test(theDictionary.D) == true)
{
Dictionary_Find(Account_String, rowindex, theDictionary.D, Cash_Value, txtCurrency.Text); //Method that makes use of the dictionary values, above dictionary checks only if it exists
}
With dictionaries from A-T, that would be alot of if/else's! Is there a better way to do this? I've found one thread mentioning this same topic, by adding the dictionaries to a dictionary array[] then looping over it, but how do I get the name of the matching dictionary if a match is found or make my second method, Dictionary_Find, use the matching dictionary?
Another possible solution, you could use reflection to get each dictionary from A-T from the DictionaryInit class. Create an array that contains values A-T, loop through the array and use reflection to get the dictionary, and test that dictionary, if you find a match, return that dictionary and exit the loop. Something like:
var dicts = new[]{"A", "B", ......., "T"}
foreach (var dict in dicts)
{
var found = CheckDictionary(theDictionary, dict);
if (found != null)
{
Dictionary_Find(Account_String, rowindex, (Dictionary<int, DictionarySetup>)found, Cash_Value, txtCurrency.Text);
break;
}
}
public static object CheckDictionary(object dictClass, string dictName)
{
var theDictionary = dictClass.GetType().GetProperty(dictName).GetValue(dictClass, null);
return Dictionary_Test(theDictionary) ? theDictionary : null;
}
I've just quickly grabbed some code from a project I've done and modified it to suit but haven't tested it. Might need a few tweaks but hopefully gets you close!
// put dictionary A ~ T to a list of dictionary
List<Dictionary<int, DictionarySetup>> dictionaries = new List<Dictionary<int, DictionarySetup>>{A,B,C, ... , T}; // Replace ... with D,E,F, etc. until T
// iterate each dictionary and if found, exit the loop
foreach(var dict in dictionaries)
{
if(Dictionary_Test(dict))
{
Dictionary_Find(Account_String, rowindex, dict, Cash_Value, txtCurrency.Text);
break;
}
}

How do I use C# generic Dictionary like the Hashtable is used in Java?

I am following this tutorial and I am working with the Dictionary that I have found out is the equivalent to the Hashtable in Java.
I created my Dictionary like so:
private Dictionary<String, Tile> tiles = new Dictionary<String, Tile>();
Though my dilemma is that when using Dictionary I can not use get, written in Java like so:
Tile tile = tiles.get(x + ":" + y);
How do I accomplish the same thing. Meaning getting x:y as the result?
Short Answer
Use the indexer or the TryGetValue() method. If the key isn't present, then the former throws a KeyNotFoundException and the latter returns false.
There is really no direct equivalent to the Java Hashtable get() method. That's because Java's get() returns null if the key isn't present.
Returns the value to which the specified key is mapped, or null if this map contains no mapping for the key.
On the other hand, in C# we can map a key to a null value. If either the indexer or the TryGetValue() says that the value associated with a key is null, then that doesn't mean the key isn't mapped. It just means that the key is mapped to null.
Running Example:
using System;
using System.Collections.Generic;
public class Program
{
private static Dictionary<String, Tile> tiles = new Dictionary<String, Tile>();
public static void Main()
{
// add two items to the dictionary
tiles.Add("x", new Tile { Name = "y" });
tiles.Add("x:null", null);
// indexer access
var value1 = tiles["x"];
Console.WriteLine(value1.Name);
// TryGetValue access
Tile value2;
tiles.TryGetValue("x", out value2);
Console.WriteLine(value2.Name);
// indexer access of a null value
var value3 = tiles["x:null"];
Console.WriteLine(value3 == null);
// TryGetValue access with a null value
Tile value4;
tiles.TryGetValue("x:null", out value4);
Console.WriteLine(value4 == null);
// indexer access with the key not present
try
{
var n1 = tiles["nope"];
}
catch(KeyNotFoundException e)
{
Console.WriteLine(e.Message);
}
// TryGetValue access with the key not present
Tile n2;
var result = tiles.TryGetValue("nope", out n2);
Console.WriteLine(result);
Console.WriteLine(n2 == null);
}
public class Tile
{
public string Name { get; set; }
}
}
Best way to get value is
bool Dictionary<Key, Value>.TryGetValue(Key key, out Value value);
It will return boolean value to determine if key was present and value is correctly referenced or not.
This method is fast, since you get out value only when key was presented, so multiple hashing and dictionary searching is avoided.
So your code will be:
private Dictionary<String, Tile> tiles = new Dictionary<String, Tile>();
Tile outValue;
if(tiles.TryGetValue( x + ":" + y, out outValue))
{
Console.WriteLine("I have this: " + outValue.ToString());
}
else
{
Console.WriteLine("I have nothing");
}
See MSDN.

How to assign key=>value pairs in a Dictionary?

Here is my code:
string[] inputs = new[] {"1:2","5:90","7:12","1:70","29:60"};
//Declare Dictionary
var results = new Dictionary<int, int>();
//Dictionary<int, int> results = new Dictionary<int, int>();
foreach(string pair in inputs)
{
string[] split = pair.Split(':');
int key = int.Parse(split[0]);
int value = int.Parse(split[1]);
//Check for duplicate of the current ID being checked
if (results.ContainsKey(key))
{
//If the current ID being checked is already in the Dictionary the Qty will be added
//Dictionary gets Key=key and the Value=value; A new Key and Value is inserted inside the Dictionary
results[key] = results[key] + value;
}
else
{
//if No duplicate is found just add the ID and Qty inside the Dictionary
results[key] = value;
//results.Add(key,value);
}
}
var outputs = new List<string>();
foreach(var kvp in results)
{
outputs.Add(string.Format("{0}:{1}", kvp.Key, kvp.Value));
}
// Turn this back into an array
string[] final = outputs.ToArray();
foreach(string s in final)
{
Console.WriteLine(s);
}
Console.ReadKey();
I want to know if the difference if there is between assigning a key=>value pair in a dictionary.
Method1:
results[key] = value;
Method2:
results.Add(key,value);
In method 1, the function Add() was not called but instead the Dictionary named 'results' assigns somehow sets a Key-Value pair by stating code in method1, I assume that it somehow adds the key and value inside the dictionary automatically without Add() being called.
I'm asking this because I'm currently a student and I'm studying C# right now.
Sir/Ma'am, your answers would be of great help and be very much appreciated. Thank you++
The Dictionary<TKey, TValue> indexer's set method (the one that is called when you do results[key] = value;) looks like:
set
{
this.Insert(key, value, false);
}
The Add method looks like:
public void Add(TKey key, TValue value)
{
this.Insert(key, value, true);
}
The only difference being if the third parameter is true, it'll throw an exception if the key already exists.
Side note: A decompiler is the .NET developers second best friend (the first of course being the debugger). This answer came from opening mscorlib in ILSpy.
If the key exists in 1) the value is overwritten. But in 2) it would throw an exception as keys need to be unique

Categories

Resources