Extract KeyValuePair<string, string> from dictionary to another dictionary<string, string> - c#

I'm new to a programming with c#. How to extract IEnumarable key value pair from dictionary that has type <string, IEnumarable<KeyValuePair<string, string>>> to another dictionary<string, string>? Preferebly using linq. Thank you in advance.
Obviously KvpValues dictionary has some values in it. It's just a pseudo code for present what i have.
Trying to do something like that:
Dictionary<string, IEnumarable<KeyValuePair<string, string>>> KvpValues = new Dictionary<string, IEnumarable<KeyValuePair<string, string>>>();
Dictionary<string,string> values = KvpValues.Values.ForEach(k=>k.Key, v=>v.Value);

It seems like what you want to do is flatten the Values from the original Dictionary into a new Dictionary. Assuming there will be no key conflicts, your code is close, you just need to convert your IEnumerable<IEnumerable<KeyValuePair>> into a IEnumerable<KeyValuePair> which is what Enumerable.SelectMany does for you:
Dictionary<string,string> values = KvpValues.Values.SelectMany(kvs => kvs).ToDictionary(k => k.Key, v => v.Value);

Related

How to add duplicate keys into the Dictionary

I have some lines from text files that i want to add into the Dictionary.I am using Dictionary for the first time.While adding up starting lines it was Ok but suddenly i got error:
An item with the same key has already been added
Here in my code there are duplicate keys which i can not change.Here is my code in c#
Dictionary<string, string> previousLines = new Dictionary<string, string> { };
previousLines.Add(dialedno, line);
Here dialedno is the key and line is the textfile line.
Here is the code from which i am retrieving the given line based on key.
string tansferOrginExt = previousLines[dialedno];
So my concern is how to allow to add duplicate keys in Dictionary if possible and if not how can i get similar functionality.
how to allow to add duplicate keys in Dictionary
It is not possible. All keys should be unique. As Dictionary<TKey, TValue> implemented:
Every key in aDictionary<TKey, TValue> must be unique according to
the dictionary's equality comparer.
Possible solutions - you can keep collection of strings as value (i.e. use Dictionary<string, List<string>>), or (better) you can use Lookup<TKey, TValue> instead of dictionary.
how to check for duplicate keys and delete previous value from
Dictionary?
You can check if the key exists with previousLines.ContainsKey(dialedno) but if you always want to hold the last line, then just replace whatever dictionary had for the key, or add the new key if it is not in the dictionary:
previousLines[dialedno] = line;
We can Use a List of Key Value Pair
List<KeyValuePair<string, string>> myduplicateLovingDictionary= new List<KeyValuePair<string, string>>();
KeyValuePair<string,string> myItem = new KeyValuePair<string,string>(dialedno, line);
myduplicateLovingDictionary.Add(myItem);
Its not possible to add duplicate items to a Dictionary - an alternative is to use the Lookup class.
Enumerable.ToLookup Method
Creates a generic Lookup from an IEnumerable.
Example:
class Program
{
private static List<KeyValuePair<string, int>> d = new List<KeyValuePair<string, int>>();
static void Main(string[] args)
{
d.Add(new KeyValuePair<string, int>("joe", 100));
d.Add(new KeyValuePair<string, int>("joe", 200));
d.Add(new KeyValuePair<string, int>("jim", 100));
var result = d.Where(x => x.Key == "joe");
foreach(var q in result)
Console.WriteLine(q.Value );
Console.ReadLine();
}
}
List< KeyValuePair < string, string>> listKeyValPair= new List< KeyValuePair< string, string>>();
KeyValuePair< string, string> keyValue= new KeyValuePair< string, string>("KEY1", "VALUE1");
listKeyValPair.Add(keyValue);
If your question is if you can add the same key twice, the answer is No.
However if you want to just iterate through the item and then increase the count of the value for the particular Key, you can achieve that by using "TryAdd" method.
var dict = new Dictionary<int, int>();
foreach (var item in array)
{
dict.TryAdd(item, 0);
dict[item]++;
}
The same thing we are trying to achieve with if else, can be achieved with this method.``
https://learn.microsoft.com/en-us/dotnet/api/system.collections.concurrent.concurrentdictionary-2.tryadd?view=netframework-4.7.2

Add an Array to a Dictionary in C#

I have tried reading the other posts on this subject and can't quite figure this out.
I have a list in C# that I want to put in a dictionary with all of the same keys. The list is this
string[] IN ={"Against","Like","Upon","Through","Of","With","Upon","On","Into","From","by","that","In","About","For"
,"Along","Before","Beneath","At","Across","beside","After","Though","Among","Toward","If"};
I want to create and populate a dictionary with the key being "IN" (the name of the array) and then having each string for the array in the dictionary.
This is what I wrote to create the dictionary (which I am not sure is correct):
Dictionary<string, List<string>> wordDictionary = new Dictionary<string, List<string>> ()
But I am not sure how to populate the dictionary.
Any help would be greatly appreciated as this is the first time I have tried to use a dictionary and I am new to C#
An array is string[], not List<string>, so just do this:
Dictionary<string, string[]> wordDictionary = new Dictionary<string, string[]>();
Now you can add your array as usual.
wordDictionary.Add("IN", IN);
Or:
wordDictionary.Add("IN", new string[] {"Against","Like","Upon","Through","Of","With","Upon","On","Into","From","by","that","In","About","For","Along","Before","Beneath","At","Across","beside","After","Though","Among","Toward","If"});
Dictionary.Add("IN", new List<string>(IN));
...if you want to keep the current signature for your dictionary.
If you change it to Dictionary<string, string[]> then you can just:
Dictionary.Add("IN",IN);
You currently have a string array, not a list - so it should be:
Dictionary<string, string[]> wordDictionary = new Dictionary<string,string[]> ()
Then you can just add items like:
wordDictionary.Add("IN" , IN);
Do you really need to convert your array into a string? You could very well use string[] instead of List in your dictionary:
var wordDictionary = new Dictionary<string, string[]>();
wordDictionary.Add("IN", IN);
But if you really want to convert your string array to List:
var wordDictionary = new Dictionary<string, List<string>>();
wordDictionary.Add("IN", IN.ToList());
Another way to add the array (it's not a list) to the dictionary is to use collection initializer:
var wordDictionary = new Dictionary<string, string[]> { "IN", IN };
This is exactly the same as creating the dictionary in a normal way and then calling Add("IN", IN).

How to create an array with label and not integer

Suppose I have an array of strings like :
myArray["hello", "my", "name", "is", "marco"]
to access to this variable, I have to put an integer as index. So if I wanto to extract the third element I just do :
myArray[2]
Now, I'd like to use label instead of integer.
So for example somethings like :
myArray["canada"]="hello";
myArray["america"]="my";
myArray["brazil"]="name";
myArray["gosaldo"]="is";
myArray["italy"]="marco";
How can I do this on C#? Is it possible? Thanks
That's called an associative array, and C# doesn't support them directly. However, you can achieve exactly the same the effect with a Dictionary<TKey, TValue>. You can add values with the Add method (which will throw an exception if you try to add an already existing key), or with the indexer directly, as below (this will overwrite the existing value if you use the same key twice).
Dictionary<string, string> dict = new Dictionary<string, string>();
dict["canada"] = "hello";
dict["america"] = "my";
dict["brazil"] = "name";
dict["gosaldo"] = "is";
dict["italy"] = "marco";
C# has a Dictionary class (and interface) to deal with this sort of storage. For example:
Dictionary<string, string> dict = new Dictionary<string, string>();
dict.Add("canada", "hello");
dict.Add("america", "my");
dict.Add("brazil", "name");
dict.Add("gosaldo", "is");
Here are the docs: http://msdn.microsoft.com/en-us/library/xfhwa508.aspx
With a Dictionary you will be able to set the "key" for each item as a string, and and give them string "values". For example:
Dictionary<string, string> dic = new Dictionary<string, string>();
dic.Add("canada", "hello");
You're looking for an associative array and I think this question is what you're looking for.

Linq and Dictionary and converting array values

I have the following code
IDictionary<string, IEnumerable<Control>>
I need to convert it to
IDictionary<string, IEnumerable<string>>
using ClientID as the new value.
Does anybody know how to do this in Linq instead iterating through the dictionary?
Thanks
Podge
Something like
IDictionary<string, IEnumerable<Control>> input = ...
IDictionary<string, IEnumerable<string>> output =
input.ToDictionary(item => item.Key,
item => item.Value.Select(control => control.ClientID));
Without having a compiler by hand, something like this should work...
dictOne
.ToDictionary(k=>k.Key, v=>v.Value.Select(c=>c.ClientID))

using dictionary as a key in other dictionary

I would like to use Dictionary as TKey in another Dictionary. Something similar to python. I tried this but it gives me errors.
Dictionary<Dictionary<string, string>, int> dict = new Dictionary<Dictionary<string, string>, int>();
Dictionary<string, string> dict2 = new Dictionary<string, string>();
dict2["abc"] = "def";
dict[dict["abc"] = 20;
What error is it giving you? Is it complaining about your missing bracket on line 4?
Line 4 looks like it should be:
dict[dict["abc"]] = 20;
However, you probably mean this, since "abc" is not a key of dict:
dict[dict2["abc"]] = 20;
But dict2["abc"] is a string, when the key of dict is supposed to be a Dictionary<string, string>.
But let's re-examine your original goal at this point before going to far down this path. You shouldn't be using mutable types as dictionary keys in the first place.
This may be the code you're looking for:
Dictionary<string, int> dict = new Dictionary<string, int>();
Dictionary<string, string> dict2 = new Dictionary<string, string>();
dict2["abc"] = "def";
dict[dict2["abc"]] = 20;
But it's hard to tell for sure.
Just to throw this in there, I often find that dealing with complicated dictionaries like you describe it's far better to use real names with them rather than trying to let the reader of the code sort it out.
You can do this one of two ways depending on personal preference. Either with a using statement to create a complier alias. Note you have to use the fully qualified type name since this is a compiler alias.
using ComplexKey = System.Collections.Generic.Dictionary<String, String>;
using ComplexType = System.Collections.Generic.Dictionary<
System.Collections.Generic.Dictionary<String, String>,
String
>;
Or you can go the full blown type way and actually create a class that inherits from Dictionary.
class ComplexKey : Dictionary<String, String> { ... }
class ComplexType : Dictionary<ComplexKey, String> { ... }
Doing this will make it far easier for both you and the reader of your code to figure out what you're doing. My general rule of thumb is if I'm creating a generic of a generic it's time to look at building some first class citizens to represent my logic rather.
It's because the "dict["abc"] is not dictionary, but "string".
The correct, what you asked is:
Dictionary<Dictionary<string, string>, int> dict = new Dictionary<Dictionary<string, string>, int>();
Dictionary<string, string> dict2 = new Dictionary<string, string>();
dict2["abc"] = "def";
dict[dict2] = 20;
But i'm not sure, this is what you realy want/need.

Categories