I've got a hashtable that I want to update from a second hashtable. For any of the keys that match I want to copy the value over. The problem I have is when I enumerate the hashtable keys and try to cast each to a string I receive an exception about casting a Guid to a String. Well it's the string I want. When you use the index operator with something like hashtable["FirstName"] then I expect FirstName to be the key. It might use Guids underneath I guess but I need to get out the string for the key, the key value.
private void UpdateSharePointFromInfoPath(Hashtable infopathFields)
{
// Go through all the fields on the infopath form
// Invalid Cast Exception Here
foreach (String fieldName in infopathFields.Keys)
{
// If the same field is on sharepoint
if (workflowProperties.Item.Fields.ContainsField(fieldName))
{
// Update the sharepoint field with the new value from infopath
workflowProperties.Item[fieldName] = infopathFields[fieldName];
}
}
// Commit the changes
workflowProperties.Item.Update();
}
EDIT
I don't create either of these hashtables. The keys have strings somewhere because I can put the field name in like the following and get the value of the field out. I'm trying to make a shorthand way of doing the following for every field:
workflowProperties.Item["FirstName"] = infopathFields["FirstName"];
workflowProperties.Item["LastName"] = infopathFields["LastName"];
workflowProperties.Item["Address"] = infopathFields["Address"];
workflowProperties.Item["DOB"] = infopathFields["DOB"];
ect...
EDIT
It's been said that the hashtable uses Guids, but it also obviously has a string inside else I wouldn't be able to do infopathFields["FirstName"]. It's the value on the string I pass in there that I want.
Every item is a Key/Value pair of format DictionaryEntry
foreach (DictionaryEntry de in infopathFields)
{
string fieldName = de.Key as string;
if (workflowProperties.Item.Fields.ContainsField(fieldName))
{
workflowProperties.Item[fieldName] = infopathFields[fieldName];
}
}
workflowProperties.Item.Update();
The standard version of the Hashtable can have different type keys, so most of your keys may be strings, but some of your keys may be GUIDs. I'm willing to bet that is the case and is causing your issue. The following little console app demonstrates the problem.
static void Main(string[] args)
{
System.Collections.Hashtable htable = new System.Collections.Hashtable();
htable.Add("MyName", "WindyCityEagle");
htable.Add("MyAddress", "Here");
htable.Add(new Guid(), "That Was My Guid");
int loopCount = 0;
foreach (string s in htable.Keys)
{
Console.WriteLine(loopCount++.ToString());
Console.WriteLine(htable[s]);
}
}
You'll get the exact same exception that you're reporting here.
My suggestion to fix the problem would be to go with the following
private void UpdateSharePointFromInfoPath(Hashtable infopathFields)
{
// Go through all the fields on the infopath form
// Invalid Cast Exception Here
foreach (object key in infopathFields.Keys)
{
string wfpKey = key.ToString();
// If the same field is on sharepoint
if (workflowProperties.Item.Fields.ContainsField(wfpKey))
{
// Update the sharepoint field with the new value from infopath
workflowProperties.Item[wfpKey] = infopathFields[key];
}
}
// Commit the changes
workflowProperties.Item.Update();
}
What creates the Hashtable? the key is actually an object so it sounds like whatever populated it has no implicit cast to a string
If the type of the values of infopathFields is a Guid then the types of the values of workflowProperties will have to be Guids. I can't see from the snippet what workflowProperties is defined as.
To convert a Guid to a string use Guid.ToString()
The objects stored in the hashtable are Guid objects, so to get a string you need to call ToString() on the object you get from the key enumerator. I would also recommend using the generic Dictionary<K,V> class instead of Hashtable, as that would catch problems like this at compile time rather than runtime.
To get largest integer key from Hash table:
public class Example
{
public void hashTableMethod()
{
Hashtable ht = new Hashtable();
ht.Add(5002894, "Hemant Kumar");
ht.Add(5002895, "Himanshee Ratnakar");
ht.Add(5002896, "Pooja Bhatnagar");
ht.Add(5002897, "Hina Saxena");
ht.Add(5002898, "Kanika Aneja");
ht.Add(5002899, "Hitesh Chaudhary");
Console.Write("\nNumber of Key-Value pair elements in HashTable are : {0}",ht.Count);
Console.WriteLine("Elements in HashTable are: ");
ICollection htkey = ht.Keys;
foreach (int key in htkey)
{
Console.WriteLine("{0}. {1}",key,ht[key]);
}
string ch="n";
do
{
Console.Write("\n\nEnter the name to check if it is exist or not, if not then it will add: ");
string newName=Console.ReadLine();
if(ht.ContainsValue(newName))
{
Console.Write("\nYour Name already Exist in the list!!");
}
else
{
Console.Write("\nSorry that name doesn't exist but it will be added!!");
int getKey = 0;
int[] htk= new int[ht.Count];
ht.Keys.CopyTo(htk,0);
string[] val=new string[ht.Count];
ht.Values.CopyTo(val,0);
Array.Sort(htk,val);
foreach (int id in htk)
{
getKey = id;
}
ht.Add(getKey+1,newName);
}
Console.Write("\nDo you want to search more??(y/n) :");
ch=Console.ReadLine();
}while(ch=="y"||ch=="Y");
Console.Write("\nNew List Items: \n");
ICollection htkeys = ht.Keys;
foreach (int key in htkeys)
{
Console.WriteLine("{0}. {1}",key,ht[key]);
}
}
}
Related
I have the following in my web.config:
<add key="someValuestoReturn" value="60,59,58,57,56"/>
I want to return a list of this integer values into my my method but i'm having a difficult to call the list of the values from the web.config:
Private int GetValues(){
var _list = System.Configuration.ConfigurationManager.AppSettings["someValuestoReturn"].ToList(); //<< doesn't work
return _list
}
What would be the best way to achieve this?
Thank you
I might suggest you to solve this on another way..
lets first create an a empty list of a strings which we are going later to put into an array:
After that we need to find your key and we need to get values from a key into our new created list, but we must take care about spliting because your values are comma separated, so check my code below:
List<string> values = new List<string>();
foreach (string key in ConfigurationManager.AppSettings)
{
if (key.StartsWith("someValuestoReturn"))
{
string value = ConfigurationManager.AppSettings[key].Split(',');
values.Add(value);
}
}
string[] myValuesfromWebConfig = values.ToArray();
And that's it, you get all of your values stored in a array called myValuesfromWebConfig
And if you want something else than a string, just change your list/array type from string to int for example..
As you can see I included
string value = ConfigurationManager.AppSettings[key].Split(',');
HERE MORE ABOUT Split method
because your values are comma separated, and I guess you would like to add them to a array/list separately.. :)
Thanks
EDIT:
Because of your error that you wrote in comment, we can skip adding it to an a array, simply delete that line, you will have your values stored in list values anyway, so at the end it migth look like this:
List<string> values = new List<string>();
foreach (string key in ConfigurationManager.AppSettings)
{
if (key.StartsWith("someValuestoReturn"))
{
string value = ConfigurationManager.AppSettings[key].Split(',');
values.Add(value);
}
}
Now if you need to read that values or do whatever you want with them, you can loop throught them and that's it, for example:
foreach(var item in values)
{
//Do whatever you want with your item
}
A string is returned not a List.
For a List use:
var _list = System.Configuration.ConfigurationManager.AppSettings["someValuestoReturn"].Split(",");
System.Configuration.ConfigurationManager.AppSettings["someValuestoReturn"].Split(',');
it will return a string array
First of all I declare a hashtable and its values. The key of a hashtable entry is a GUID and the value is an object with a few string values.
Guid g = Guid.NewGuid();
Hashtable hash = new Hashtable();
InstallationFiles instFiles = new InstallationFiles(string1, string2, string3);
hash.Add(g, instFiles);
//...add many other values with different GUIDs...
My goal is to give a user a possibility to EDIT string 1, string2, string3. To cut a long story short, I am in a position where I can get the "GUID g" of the entry which needs to be edited:
public void edit()
{
//here I retrieve the GUID g of the item which has to be edited:
object objectHash = item.Tag;
//here i loop through all hash entries to find the editable one:
foreach(DictionaryEntry de in hash)
{
if(de.Key.ToString() == objectHash)
{
//here I would like to access the selected entry and change string1 -
//the line below is not working.
hash[de.Key].string1 = "my new value";
}
}
}
How do I make this line work?
hash[de.Key].string1 = "my new value";
Use Dictionary<Guid, InstallationFiles> instead HashTable
upd. You can use this.
(hash[de.Key] as InstallationFiles).string1 = "asdasd"
Ok, explanation:
Because Hashtable is not generic type, it contains references on keys and values as Objects.
Thats why, when you access to your value hashtable[mykey], you got reference to Object. To make it as reference to your type (InstallationFiles), you have to from "reference to Object" get "reference to InstallationFiles". Im my sample I use "as" operator to do this.
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.
I have objects in hashtable, in that object I have a list, how to access it?
ls.cs
class lh
{
public string name;
public List<ulong> nList = new List<ulong>();
public lh(string name)
{
this.name = name; ;
}
}
Program.cs
static void Main(string[] args)
{
while((line=ps.ReadLine()) != null)
{
gen.h_lh.Add(line, new lh(line));
}
}
public class gen
{
public static Hashtable h_lh = new Hashtable();
}
this works. when I debug I can see the object created in the hashtable; I just cant/dont know how to access/store value to the list
it's gotta be something like gen.h_lh[lh].something right ? but this didnt work. what did I miss?
First of all Hashtable is obsolete, use Dictionary<TKey, TValue> instead (Dictionary<string, lh> in your case).
Given a key, you can access the value of that key with: h_lh[key].
Or you can enumerate all of the key/value pairs with:
foreach (KeyValuePair<string, lh> pair in h_lh)
pair.Value // this is an lh object
You can also enumerate just keys h_lh.Keys, or just values h_lh.Values.
A hash tables is a data structure that represents a set. That means that by definition, you don't want to access the hash table to get an element, you just want to add, remove, or aks if an element exists. These are the basic operations with sets.
This said, HashSet<T> in .NET has no indexer. Why? Consider the line that you wrote yourself:
var item = gen.h_lh[lh]
If you really can provide the lh to index, what do you expect the hash table to give you? The same instance? Of course not, you already have it, if you are using it in the indexer. So perhaps your problem it's not very well determined.
First of all you need to determine why (and how) you want to access the elements. All you want is to iterate through all of them, or you want to quickly index any one of them? If you just want to get all the elements at some point, then you have all you need: HashSet<T> implements IEnumerable<T>. If you need to get an specific element, then you must have some key to identify the element (like the name property here), and in this case what you want is not a HashSet<lh> but a Dictionary<string,lh>, just like #Tergiver said.
foreach(System.System.Collections.DictionaryEntry entry in h_lh)
{
Console.WriteLine("Key: " + entry.Key.ToString() + " | " + "Value: " + entry.Value.ToString());
}
or you could access it using a key
lh myLh = h_lh[line];
Update answer for comment
foreach(System.System.Collections.DictionaryEntry entry in h_lh)
{
List<ulong> nList = (ulong)entry.Value;
nList.Add(1);
}
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