How to loop through this dictionary - c#

I have declared a dictionary like this:
Dictionary<string, KeyValuePair<string, string>> dc = new Dictionary<string, KeyValuePair<string, string>>();
now how can I loop through it? I wanted something like the following so I created that dictionary:
name1
oldValue1
newValue1
name2
oldValue2
newValue2
...

You can loop through it like so
foreach (var pair in dc)
{
string name = pair.Key;
string oldValue = pair.Value.Key;
string newValue = pair.Value.Value;
// use the values
}
But I have a feeling you're using the wrong tool for the job. It sounds to me like you really need to go ahead and define a proper class to hold the names and values, and then just work with a List<T> of that class.

foreach( KeyValuePair<string, string> kvp in dc )
{
Console.WriteLine("Key = {0}, Value = {1}", kvp.Key, kvp.Value);
}
When you loop a dictionary you use KeyValuePair that is generic. Since your dictionary contain the key as string and the value as string, this one will take also a string for both.
You can access the key with kvp.Key and the value with kvp.Value.
For your example, you are using a Dictionary of string that contain a value of KeyValuePair.
So, you can have the exact print you want with :
foreach( KeyValuePair<string, KeyValuePair<string,string>> kvp in dc )
{
Console.WriteLine(kvp.Key + " " + kvp.Value.Key + " "+ kvp.Value.Value);
}

Related

How do I iterate over a Dictionary<string, StringValues> collection obtained from QueryHelpers.ParseQuery?

When I call
QueryHelpers.ParseQuery(uri.Query);
it returns
Dictionary<string, StringValues>
When I view this collection in the Visual Studio "Locals" window, I see something like this:
Count = 4
{[q, {qOne, qTwo}]}
"q"
{qOne, qTwo}
{[selection, {sOne, sTwo}]}
"selection"
{sOne, sTwo}
{[color, {cOne, cTWo}]}
"color"
{cOne, cTwo}
{[option, {oOne, oTwo}]}
"option"
{oOne, oTwo}
If I look at the Microsoft documentation for StringValues it says:
GetEnumerator() - Retrieves an object that can iterate through the individual strings in this StringValues.
That tells me that I should be able to do something like this:
Dictionary<string, StringValues> queryString = QueryHelpers.ParseQuery(uri.Query);
foreach(string key in queryString.Keys){
Console.WriteLine("KEY: " + key);
foreach(string value in queryString.Value[key].GetEnumerator()){
Console.WriteLine("VALUE: " + value);
}
}
But there isn't any option for that queryString.Value[key] that I need to do this.
So, how do I iterate over this particular Dictionary<string, StringValues> collection?
Dictionary<string, StringValues> queryStrings = QueryHelpers.ParseQuery(uri.Query);
foreach(var stringValues in queryString.Values){
foreach(var value in stringValues)
Console.WriteLine("VALUE: " + value);
}
If you need the keys:
Dictionary<string, StringValues> queryStrings = QueryHelpers.ParseQuery(uri.Query);
foreach(var key in queryString.Keys){
Console.WriteLine("KEY: " + key);
foreach(var value in queryString[key]){
Console.WriteLine("VALUE: " + value);
}
}

Extract key value pair from dictionary

I'm at the first step in programming and i'm stuck with a problem with Dictionary(key value) pair.
The statement of the problem is:
Write a console application that extracts and prints the key and value on a line.
Example:
For input data:
year:2018
The console will display:
year
2018
here is my code:
string inputData = Console.ReadLine();
Dictionary<string, int> dictionary = new Dictionary<string, int>();
dictionary.Add(inputData, 2018 );
foreach (KeyValuePair<string, int> kvp in dictionary)
{
Console.WriteLine("{0}\n{1}", kvp.Key, kvp.Value);
}
// expects year:2018
var inputData = Console.ReadLine();
// split by ':' to get 'year' and '2018' values
var values = inputData.Split(':');
// creates a dictionary
var dictionary = new Dictionary<string, int>();
// add the 'year' string as key and '2018' as value
dictionary.Add(values[0], Convert.ToInt32(values[1]));
// print all the dictionary
foreach (var kvp in dictionary)
{
Console.WriteLine("{0}\n{1}", kvp.Key, kvp.Value);
}
However, the problem description is not asking you to use a dictionary.
So, instead of creating a dictionary, you can simply print the values.
var inputData = Console.ReadLine();
var values = inputData.Split(':');
Console.WriteLine(values[0]);
Console.WriteLine(values[1]);

Dictionary<string, List <KeyValuePair<string,string>>>

I have created:
Dictionary<string, List <KeyValuePair<string,string>>> diction = new Dictionary<string, List<KeyValuePair<string,string>>>();
Later I've added to that list:
diction.Add(firststring, new List<KeyValuePair<string,string>>());
diction[firststring].Add(new KeyValuePair<string, string>(1ststringlist, 2ndstringlist));
So now, If I want to read and show on screen this dictionary, how would I do it with foreach loop ? It's like 3 dimmension syntax, don't now how to create it and access it.
Also can anyone explain how to read this part?
diction[firststring].Add
What this marks [] excatly mean? I read whole dictionary there?
thank You for answer and Your time.
Dictionaries store key / value pairs. In your case, your key type is string and value type is List <KeyValuePair<string,string>>.So when you do:
diction[firststring]
firststring is your Key and you are trying to access a List <KeyValuePair<string,string>>.Your best option is nested loops I think.if you want to display all values. For example:
foreach(var key in dict.Keys)
{
// dict[key] returns List <KeyValuePair<string,string>>
foreach(var value in dict[key])
{
// here type of value is KeyValuePair<string,string>
var currentValue = value.Value;
var currentKey = value.Key;
}
}
For printing the datastructure, try this:
// string.Join(separator, enumerable) concatenates the enumerable together with
// the separator string
var result = string.Join(
Environment.NewLine,
// on each line, we'll render key: {list}, using string.Join again to create a nice
// string for the list value
diction.Select(kvp => kvp.Key + ": " + string.Join(", ", kvp.Value)
);
Console.WriteLine(result);
In general, to loop over the values of a dictionary, you can use foreach or LINQ just like with any IEnumerable data structure. IDictionary is an IEnumerable>, so the foreach variable will be of type KeyValuePair.
The syntax diction[key] allows you to get or set the value of the dictionary stored at the index key. It's similar to how array[i] lets you get or set the array value at index i. For example:
var dict = new Dictionary<string, int>();
dict["a"] = 2;
Console.WriteLine(dict["a"]); // prints 2
If all you need to do is store rows of 3 string values each, then the data structure you are using is far too complicated.
Here's a much simpler example, based on the Tuple class:
public class Triplet : Tuple<string, string, string>
{
public Triplet(string item1, string item2, string item3) : base(item1, item2, item3)
{
}
}
So you just define a class Triplet that holds 3 strings, like above. Then you simply create a List of Triplets in your code:
// Your code here
var data = new List<Triplet>();
// Add rows
data.Add(new Triplet("John", "Paul", "George"));
data.Add(new Triplet("Gene", "Paul", "Ace"));
// Display
foreach(Triplet row in data)
{
Console.WriteLine("{0}, {1}, {2}", row.Item1, row.Item2, row.Item3);
}
and this is far simpler to read, understand, and maintain.

Logging Hashtable Properties

I have a Hashtable that I am trying to log the values for. the name of the Hashtable is "props".
My code is as follows:
Dictionary<string, string> keyPairs = new Dictionary<string, string>();
foreach (KeyValuePair<string, string> items in props)
{
keyPairs.Add(items.Key, items.Value);
}
Logging.Instance.WriteInformation(string.Format("Key: {0} \t Value: {1}", keyPairs.Keys, keyPairs.Values));
However this results in a InvalidCastException at runtime.
Is there an easier/more sensible way to log key/value pairs?
Ideally the output would look something like so:
key1 value1
key2 value2
key3 value3
etc.
As an addition thought, in debugging, the exception seems to occur right at the start of the foreach loop. I have also tried setting it up as KeyValuePair<string, object> but I get the same InvalidCastException.
Would this possibly have something to do with KeyValuePair being inside System.Collections.Generic and Hashtable being inside System.Collections?
You can either use a loop or, if you want an one-liner:
var allPairs = string.Join(Environment.NewLine,
keyPairs.Select(kvp => string.Format("Key: {0} \t Value: {1}", kvp.Key, kvp.Value)));
Logging.Instance.WriteInformation(allPairs);
Sure, just loop:
for (var entry : keyPairs)
{
Logging.Instance.WriteInformation(string.Format("Key: {0} \t Value: {1}",
entry.Key, entry.Value);
}
It's only a few lines - you could easily put it in a method if you need it in more than one place.
Log while you are looping.
Dictionary<string, string> keyPairs = new Dictionary<string, string>();
foreach (KeyValuePair<string, string> items in props)
{
keyPairs.Add(items.Key, items.Value);
Logging.Instance.WriteInformation(string.Format("Key: {0} \t Value: {1}", items.Key, items.Value));
}

Is there anyway to handy convert a dictionary to String?

I found the default implemtation of ToString in the dictionary is not what I want. I would like to have {key=value, ***}.
Any handy way to get it?
If you just want to serialize for debugging purposes, the shorter way is to use String.Join:
var asString = string.Join(Environment.NewLine, dictionary);
This works because IDictionary<TKey, TValue> implements IEnumerable<KeyValuePair<TKey, TValue>>.
Example
Console.WriteLine(string.Join(Environment.NewLine, new Dictionary<string, string> {
{"key1", "value1"},
{"key2", "value2"},
{"key3", "value3"},
}));
/*
[key1, value1]
[key2, value2]
[key3, value3]
*/
Try this extension method:
public static string ToDebugString<TKey, TValue> (this IDictionary<TKey, TValue> dictionary)
{
return "{" + string.Join(",", dictionary.Select(kv => kv.Key + "=" + kv.Value).ToArray()) + "}";
}
How about an extension-method such as:
public static string MyToString<TKey,TValue>
(this IDictionary<TKey,TValue> dictionary)
{
if (dictionary == null)
throw new ArgumentNullException("dictionary");
var items = from kvp in dictionary
select kvp.Key + "=" + kvp.Value;
return "{" + string.Join(",", items) + "}";
}
Example:
var dict = new Dictionary<int, string>
{
{4, "a"},
{5, "b"}
};
Console.WriteLine(dict.MyToString());
Output:
{4=a,5=b}
Maybe:
string.Join
(
",",
someDictionary.Select(pair => string.Format("{0}={1}", pair.Key.ToString(), pair.Value.ToString())).ToArray()
);
First you iterate each key-value pair and format it as you'd like to see as string, and later convert to array and join into a single string.
No handy way. You'll have to roll your own.
public static string ToPrettyString<TKey, TValue>(this IDictionary<TKey, TValue> dict)
{
var str = new StringBuilder();
str.Append("{");
foreach (var pair in dict)
{
str.Append(String.Format(" {0}={1} ", pair.Key, pair.Value));
}
str.Append("}");
return str.ToString();
}
I got this simple answer.. Use JavaScriptSerializer Class for this.
And you can simply call Serialize method with Dictionary object as argument.
Example:
var dct = new Dictionary<string,string>();
var js = new JavaScriptSerializer();
dct.Add("sam","shekhar");
dct.Add("sam1","shekhar");
dct.Add("sam3","shekhar");
dct.Add("sam4","shekhar");
Console.WriteLine(js.Serialize(dct));
Output:
{"sam":"shekhar","sam1":"shekhar","sam3":"shekhar","sam4":"shekhar"}
If you want to use Linq, you could try something like this:
String.Format("{{{0}}}", String.Join(",", test.OrderBy(_kv => _kv.Key).Zip(test, (kv, sec) => String.Join("=", kv.Key, kv.Value))));
where "test" is your dictionary. Note that the first parameter to Zip() is just a placeholder since a null cannot be passed).
If the format is not important, try
String.Join(",", test.OrderBy(kv => kv.Key));
Which will give you something like
[key,value], [key,value],...
Another solution:
var dic = new Dictionary<string, double>()
{
{"A", 100.0 },
{"B", 200.0 },
{"C", 50.0 }
};
string text = dic.Select(kvp => kvp.ToString()).Aggregate((a, b) => a + ", " + b);
Value of text: [A, 100], [B, 200], [C, 50]
You can loop through the Keys of the Dictionary and print them together with the value...
public string DictToString(Dictionary<string, string> dict)
{
string toString = "";
foreach (string key in dict.Keys)
{
toString += key + "=" + dict[key];
}
return toString;
}
I like ShekHar_Pro's approach to use the serializer. Only recommendation is to use json.net to serialize rather than the builtin JavaScriptSerializer since it's slower.
I really like solutions with extension method above, but they are missing one little thing for future purpose - input parametres for separators, so:
public static string ToPairString<TKey, TValue>(this Dictionary<TKey, TValue> dictionary, string pairSeparator, string keyValueSeparator = "=")
{
return string.Join(pairSeparator, dictionary.Select(pair => pair.Key + keyValueSeparator + pair.Value));
}
Example of using:
string result = myDictionary.ToPairString(Environment.NewLine, " with value: ");
What you have to do, is to create a class extending Dictionary and overwrite the ToString() method.
See you

Categories