Retrieving data from Dictionary C# - c#

So i am currently creating a program that maps a String key and a ArrayList of objects (currently integers)
Now i have created a class called Operator that has a method which returns a Dictionary.
To test the output of my Dictionary i decided to make pop (Messagebox) that displays the integer value.
However this proved to be a deal breaker for me. After abit of research i managed to assemble the following code:
Operator op = new Operator();
ArrayList a;
op.startCollecting().TryGetValue("Henvendelser", out a);
int value = (int) a[0];
MessageBox.Show("" + value);
Note the startCollecting method returns the Dictionary
When trying to get the data i first have to create a new empty ArrayList, clone my existing ArrayList into that ArrayList, create an integer value, pull the item from the ArrayList at index 0 and then show the messagebox.
I am originally a java programmer, and in Java i would have been able to do this:
int value = op.startCollecting().get("Henvendelser").get(0);
Am i doing it wrong in C#? is there an easier way of Retrieving data?

First things first: You should use generic lists instead of ArrayList in c#.
To your question:
Dictonary<string, List<int>> dictonary = op.startCollecting();
if(dictonary.ContainsKey("Henvendelser"))
{
List<int> list = dictonary["Henvendelser"];
int value = list[0];
MessageBox.Show(value.ToString());
}

You can retrieve your value like this :
var value = op.startCollection()["Henvendelser"];

Assuming your StartCollecting method roughly looks like this...
class Operator
{
public IDictionary<string, IList<int>> StartCollecting()
{
...
}
}
... you can use the indexers of IDictionary and IList to retrieve your value:
op.StartCollecting()["Henvendelser"][0]

Related

Do multidimensional arrays have to be of the same type? [duplicate]

I want to create two dimension array of different type like I can add to that array two values one of them is controlname and second is boolean value.
You can't do that. Instead, you should create a class that contains these two properties, then you can create an array of that type:
public class MyClass
{
public string ControlName {get;set;}
public bool MyBooleanValue {get;set;}
}
public MyClass[] myValues=new MyClass[numberOfItems];
Or, as Anders says, use a dictionary if one of the properties is meant to be used to perform lookups.
A dictionary will work for what you are trying to do then.
Dictionary<string, bool> controllerDictionary = new Dictionary<string, bool>();
To set a value
if (controllerDictionary.ContainsKey(controllerName))
controllerDictionary[controllerName] = newValue;
else
controllerDictionary.Add(controllerName, newValue);
To get a value
if (controllerDictionary.ContainsKey(controllerName))
return controllerDictionary[controllerName];
else
//return default or throw exception
You can't to that with an array.
Perhaps you should be using a Dictionary?
A generic dictionary of Dictionary<string,bool> appears to be the kind of thing that will work for your description.
It depends on how you want to use your array. Do you want to look up the value by a key, or by its index? Konamiman suggested a class. But a class with two types is nothing more than a Dictionary<type of key, type of value>.
You can use a dictionary if you want to obtain the value by a key.
Like so:
Dictionary<string, int> MyDict = new Dictionary<string, int>();
MyDict.Add("Brutus", 16);
MyDict.Add("Angelina", 22);
int AgeOfAngelina = MyDict["Angelina"];
Now the disadvantage of a dictionary is that, you can't iterate over it. The order is undetermined. You can not use MyDict[0].Value to obtain the age of Brutus (which is 16).
You could use a
List<KeyValuePair<string, int>> MyList = new List<KeyValuePair<string, int>>();
to iterate through a 2D array of two different types as a List supports iteration. But then again, you cannot obtain the age of Angelina by MyList["Angelina"].Value but you would have to use MyList[0].Value.
But you could use a datatable as well. But it requires somewhat more work to initialize the table with its columns.
If you want to lookup/set a boolean by control name, you could use a Dictionary<string, bool>.
Use Dictionary<string,bool>.
If, for some reason, you really need an array, try object[,] and cast its values to the types you want.
Another way of doing it is to create an array of type object, and then add this to an arraylist.
Here is some sample code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Collections;
using System.Collections.Generic;
namespace Collections
{
class Program
{
static void Main(string[] args)
{
ArrayList ar = new ArrayList();
object[] o = new object[3];
// Add 10 items to arraylist
for (int i = 0; i < 10; i++)
{
// Create some sample data to add to array of objects of different types.
Random r = new Random();
o[0] = r.Next(1, 100);
o[1] = "a" + r.Next(1,100).ToString();
o[2] = r.Next(1,100);
ar.Add(o);
}
}
}
}
"A multi-dimensional array is an array:
all elementsin all dimensions have the same type"
Actually you can do it with a List. I suggest you take a look at Tuples.
How to easily initialize a list of Tuples?
You can use a list of type object too if you want
Like so :
List<List<object>> Dates = new List<List<object>>() { };
Dates.Add(new List<object>() { 0 ,"January 1st" });

Store variables in list/array and loop through later c#

Sorry, I think I was not clear earlier. I am trying to do as O.R.mapper says below- create a list of arbitrary variables and then get their values later in foreach loop.
Moreover, all variables are of string type so I think can come in one list. Thanks.
Is there a way to store variables in a list or array then then loop through them later.
For example: I have three variables in a class c named x,y and Z.
can I do something like:
public List Max_One = new List {c.x,c.y,c.z}
and then later in the code
foreach (string var in Max_One)
{
if ((var < 0) | (var > 1 ))
{
// some code here
}
}
Is there a particular reason why you want to store the list of variables beforehand? If it is sufficient to reuse such a list whenever you need it, I would opt for creating a property that returns an IEnumerable<string>:
public IEnumerable<string> Max_One {
get {
yield return c.x;
yield return c.y;
yield return c.z;
}
}
The values returned in this enumerable would be retrieved only when the property getter is invoked. Hence, the resulting enumerable would always contain the current values of c.x, c.y and c.z.
You can then iterate over these values with a foreach loop as alluded to by yourself in your question.
This might not be practical if you need to gradually assemble the list of variables; in that case, you might have to work with reflection. If this is really required, please let me know; I can provide an example for that, but it will become more verbose and complex.
Yes, e.g. if they are all strings:
public List<string> Max_One = new List<string> {c.x,c.y,c.z};
This uses the collection initializer syntax.
It doesn't make sense to compare a string to an int, though. This is a valid example:
foreach (string var in Max_One)
{
if (string.IsNullOrEmpty(var))
{
// some code here
}
}
If your properties are numbers (int, for example) you can do this:
List<int> Max_One = new List<int> { c.x, c.y, c.Z };
and use your foreach like this
foreach(int myNum in Max_One) { ... } //you can't name an iterator 'var', it's a reserved word
Replace int in list declaration with the correct numeric type (double, decimal, etc.)
You could try using:
List<object> list = new List<object>
{
c.x,
c.y,
c.z
};
I will answer your question in reverse way
To start with , you cannot name your variable with "var" since it is reserved name. So what you can do for the foreach is
foreach (var x in Max_One)
{
if ((x< 0) || (x> 1 ))
{
// some code here
}
}
if you have .Net 3.0 and later framework, you can use "var" to define x as a member of Max_One list without worrying about the actual type of x. if you have older than the version 3.0 then you need to specify the datatype of x, and in this case your code is valid (still risky though)
The last point (which is the your first point)
public List Max_One = new List {c.x,c.y,c.z}
There are main thing you need to know , that is in order to store in a list , the members must be from the same datatype, so unless a , b , and c are from the same datatype you cannot store them in the same list EXCEPT if you defined the list to store elements of datatype "object".
If you used the "Object" method, you need to cast the elements into the original type such as:
var x = (int) Max_One[0];
You can read more about lists and other alternatives from this website
http://www.dotnetperls.com/collections
P.s. if this is a homework, then you should read more and learn more from video tutorials and books ;)

Converting a KeyValuePair collection in to anonymous type

Is it possible to convert a a IEnumerable<KeyValuePair<string,string>> of KeyValuePair to an anonymous type?
Dictionary<string, string> dict= new Dictionary<string, string>();
dict.add("first", "hello");
dict.add("second", "world");
var anonType = new{dict.Keys[0] = dict[0], dict.Keys[1] = dict[1]};
Console.WriteLine(anonType.first);
Console.WriteLine(anonType.second);
********************output*****************
hello
world
The reason i would like to do this is because I am retrieving an object from a webservice that represents an object that does not exist in the wsdl. The returned object only contains a KeyValuePair collection that contains the custom fields and their values. These custom fields can be named anything, so i cant really map an xml deserialization method to the final object i will be using (whose properties must be bound to a grid).
*Just because I used Dictionary<string,string> does not mean it is absolutely a dictionary, i just used it for illustration. Really its an IEnumerable<KeyValuePair<string,string>>
Ive been trying to thing of a way to do this, but am drawing a blank. This is c# .NET 4.0.
You could use the ExpandoObject, it is based on a dictionary.
I think there are a lot of ways to achieve this, but actually converting it in the same Dictionary seems a bit odd to do.
One way to accomplish this, by not actually converting everyting is the following:
public class MyDictionary<T,K> : Dictionary<string,string> // T and K is your own type
{
public override bool TryGetValue(T key, out K value)
{
string theValue = null;
// magic conversion of T to a string here
base.TryGetValue(theConvertedOfjectOfTypeT, out theValue);
// Do some magic conversion here to make it a K, instead of a string here
return theConvertedObjectOfTypeK;
}
}
ExpandoObject is the best option, which I believe is a wrapper around some XML. You could also use an XElement:
var result = new XElement("root");
result.Add(new XElement("first", "hello"));
result.Add(new XElement("second", "world"));
Console.WriteLine(result.Element("first").Value);
Console.WriteLine(result.Element("second").Value);
foreach (var element in result.Elements())
Console.WriteLine(element.Name + ": " + element.Value);
I haven't used ExpandoObject, so I'd try that first because I understand it does exactly what you want and is also something new and interesting to learn.

Store Collection of Data Fields and Retrieve Via Identifier

In C#, how can I store a collection of values so if I want to retrieve a particular value later, I can do something like:
myCollection["Area1"].AreaCount = 50;
or
count = myCollection["Area1"].AreaCount;
Generic list?
I'd like to store more than one property to a "key". Is a class the answer?
You're looking for the Dictionary<string, YourClass> class. (Where YourClass has an AreaCount property)
EDIT
Based on your comment, it seems like you want a Dictionary (as already suggested) where your object holds all your 'values.'
For Instance:
public class MyClass
{
public int AreaCount;
public string foo;
public bool bar;
}
//Create dictionary to hold, and a loop to make, objects:
Dictionary<string, MyClass> myDict = new Dictionary<string, MyClass>();
while(condition)
{
string name = getName(); //To generate the string keys you want
MyClass mC = new MyClass();
myDict.Add(name, mC);
}
//pull out yours and modify AreaCount
myDict["Area1"].Value.AreaCount = 50;
Alternatively, you could add a string "Name" to you class (I'm using fields for the example, you'd probably use properties) and use Linq:
//Now we have a list just of your class (assume we've already got it)
myClass instanceToChange = (from items in myList
where Name == "Area1"
select item).FirstOrDefault();
myClass.AreaCount = 50;
Does that help more?
ORIGINAL RESPONSE
I'm not completely sure what you're asking, but I'll give it ago.
Given a list of Objects from which you need to grab a particular object, there are (generally) 4 ways- depending on your specific needs.
The Generic List<T> really only does this well at all if your object already supports some kind of searching (like String.Contains()).
A SortedList uses IComparer to compare and sort the Key values and arrange the list that way.
A Dictionary stores a Key and Value so that KeyValuePair objects can be retrieved.
A HashTable uses Keys and Values where the Keys must implement GetHashCode() and ObjectEquals
The specific one you need will vary based on your specific requirements.
This functionality is provided by indexers

Defining two dimensional Dynamic Array with different types

I want to create two dimension array of different type like I can add to that array two values one of them is controlname and second is boolean value.
You can't do that. Instead, you should create a class that contains these two properties, then you can create an array of that type:
public class MyClass
{
public string ControlName {get;set;}
public bool MyBooleanValue {get;set;}
}
public MyClass[] myValues=new MyClass[numberOfItems];
Or, as Anders says, use a dictionary if one of the properties is meant to be used to perform lookups.
A dictionary will work for what you are trying to do then.
Dictionary<string, bool> controllerDictionary = new Dictionary<string, bool>();
To set a value
if (controllerDictionary.ContainsKey(controllerName))
controllerDictionary[controllerName] = newValue;
else
controllerDictionary.Add(controllerName, newValue);
To get a value
if (controllerDictionary.ContainsKey(controllerName))
return controllerDictionary[controllerName];
else
//return default or throw exception
You can't to that with an array.
Perhaps you should be using a Dictionary?
A generic dictionary of Dictionary<string,bool> appears to be the kind of thing that will work for your description.
It depends on how you want to use your array. Do you want to look up the value by a key, or by its index? Konamiman suggested a class. But a class with two types is nothing more than a Dictionary<type of key, type of value>.
You can use a dictionary if you want to obtain the value by a key.
Like so:
Dictionary<string, int> MyDict = new Dictionary<string, int>();
MyDict.Add("Brutus", 16);
MyDict.Add("Angelina", 22);
int AgeOfAngelina = MyDict["Angelina"];
Now the disadvantage of a dictionary is that, you can't iterate over it. The order is undetermined. You can not use MyDict[0].Value to obtain the age of Brutus (which is 16).
You could use a
List<KeyValuePair<string, int>> MyList = new List<KeyValuePair<string, int>>();
to iterate through a 2D array of two different types as a List supports iteration. But then again, you cannot obtain the age of Angelina by MyList["Angelina"].Value but you would have to use MyList[0].Value.
But you could use a datatable as well. But it requires somewhat more work to initialize the table with its columns.
If you want to lookup/set a boolean by control name, you could use a Dictionary<string, bool>.
Use Dictionary<string,bool>.
If, for some reason, you really need an array, try object[,] and cast its values to the types you want.
Another way of doing it is to create an array of type object, and then add this to an arraylist.
Here is some sample code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Collections;
using System.Collections.Generic;
namespace Collections
{
class Program
{
static void Main(string[] args)
{
ArrayList ar = new ArrayList();
object[] o = new object[3];
// Add 10 items to arraylist
for (int i = 0; i < 10; i++)
{
// Create some sample data to add to array of objects of different types.
Random r = new Random();
o[0] = r.Next(1, 100);
o[1] = "a" + r.Next(1,100).ToString();
o[2] = r.Next(1,100);
ar.Add(o);
}
}
}
}
"A multi-dimensional array is an array:
all elementsin all dimensions have the same type"
Actually you can do it with a List. I suggest you take a look at Tuples.
How to easily initialize a list of Tuples?
You can use a list of type object too if you want
Like so :
List<List<object>> Dates = new List<List<object>>() { };
Dates.Add(new List<object>() { 0 ,"January 1st" });

Categories