compare dictionaries - c#

i have 3 generic dictionaries
static void Main(string[] args)
{
Dictionary<string, string> input = new Dictionary<string, string>();
input.Add("KEY1", "Key1");
Dictionary<string, string> compare = new Dictionary<string, string>();
compare.Add("KEY1", "Key1");
compare.Add("KEY2", "Key2");
compare.Add("KEY3", "Key3");
Dictionary<string, string> results = new Dictionary<string, string>();
i'd like to take the list of input and compare each value to the compareTo list and if it doesn't exist add it to the results list?

You can use the LINQ Except() method:
foreach (var pair in compare.Except(input))
{
results[pair.Key] = pair.Value;
}
This will perform a set difference (in effect subtracting input from compare and returning what is left over), which we can then add to the results dictionary.
Now, if results has no previous values, and you just want it to be the results from that current operation, you can just do that directly:
var results = compare.Except(input)
.ToDictionary(pair => pair.Key, pair => pair.Value);
This is assuming you want the difference in keys and values. If you had a different value (same key), it would show in the difference.
That is, for your example above results will have:
[KEY2, Key2]
[KEY3, Key3]
But if your example data was:
Dictionary<string, string> input = new Dictionary<string, string>();
input.Add("KEY1", "Key1");
Dictionary<string, string> compare = new Dictionary<string, string>();
compare.Add("KEY1", "X");
compare.Add("KEY2", "Key2");
compare.Add("KEY3", "Key3");
The results would be:
[KEY1, X]
[KEY2, Key2]
[KEY3, Key3]
Due to the fact KEY1's value was different.
If you do want only where keys or values are not contained in the other, you can do the Except on the Keys or Values collections of the dictionary instead.

dict[key] gives you the value whose key is key.
dict.ContainsKey(key) and dict.ContainsValue(value) are methods you can use to check whether a key or a value are in the dictionary. ContainsKey is more time-efficient.

Related

Is it possible to store a KeyValuePair of a dictionary without the use of a foreach loop?

The syntax for iterating over a dictionary with a foreach loop is:
foreach (KeyValuePair<key, value> item in dictionary)
Inside the foreach loop the key is accessed with item.key and the value with item.value.
This got me thinking, can this be used without the use of a foreach loop as a convenient (although niche) way to represent a specific dictionary pair?
I am not looking for some weird work arounds, like running a foreach loop and saving the KeyValuePair into a variable once the target key is reached, because at this point it would be more convenient to just use 2 variables.
Like this
var dic = new Dictionary<string, int>();
dic["a"] = 42;
KeyValuePair<string, int> keyVal;
foreach(var kv in dic) {
keyVal = kv; << gets the last entry from the dictioanry
}
Note that the dictionary does not store KeyValuePairs, it creates one for the enumeration, so the simple thing to do is this (because we are not expensively recreating something)
var dic = new Dictionary<string, int>();
dic["a"] = 42;
KeyValuePair<string, int> keyVal = new KeyValuePair<string, int>("a", dic["a"]);
this is more efficient than the (neat) LINQ Sinlge method
The IDictionary<TKey, TValue> interface implements IEnumerable<KeyValuePair<TKey,TValue>>. This means you can simply use Single() to get the entry you want.
IDictionary<string, int> dict = ...;
KeyValuePair<string, int> entry = dict.Single(it => it.Key == "yourKey");
try this
var dict = new Dictionary<string, string>() {
{"hi","Hello World!"},
{"adieu","Goodby"}
};
string hi = dict["hi"]; //Hello World!
or if you want a list
List<KeyValuePair<string,string>> list = dict.ToList();
result
[{"Key":"hi","Value":"Hello World!"},{"Key":"adieu","Value":"Goodby"}]

How to compare two dictionaries in C#?

There are different count and different order of dictionaries
If the key of list A and list B match, I would like to bring the value of list B and modify the value of list A.
Sample Code :
public static List<Dictionary<string, string>> ListDicOne = new List<Dictionary<string, string>>();
public static List<Dictionary<string, string>> ListDicTwo = new List<Dictionary<string, string>>();
(...)
ListDicOne[0].Add("ABCD", ""); // empty value
ListDicOne[1].Add("ABCD", "");
ListDicOne[2].Add("EFGH", "test");
ListDicTwo[0].Add("AABC", "oooo");
ListDicTwo[1].Add("ABCD", "WOW");
ListDicTwo[2].Add("CCDD", "haha");
ListDicTwo[3].Add("CCDD", "haha");
expected result value :
// Console Write key and value of ListDicA
ABCD \t WOW
ABCD \t WOW
EFGH \t test
I will take a guess and assume you really only want to deal with two dictionaries, and not two lists of many one-item dictionaries, which would not make any sense at all.
First, the dictionaries should be declared like this (I also assume they don't have to be public):
private static Dictionary<string, string> ListDicOne = new Dictionary<string, string>();
private static Dictionary<string, string> ListDicTwo = new Dictionary<string, string>();
And then, the usage could be like this:
ListDicOne.Add("AABC", ""); // I changed the key, they must be unique
ListDicOne.Add("ABCD", "");
ListDicOne.Add("EFGH", "test");
ListDicTwo.Add("AABC", "oooo");
ListDicTwo.Add("ABCD", "WOW");
ListDicTwo.Add("CCDD", "haha");
ListDicTwo.Add("CCDE", "haha"); // I changed the key, they must be unique
foreach (var item in ListDicTwo)
{
if (ListDicOne.ContainsKey(item.Key))
ListDicOne[item.Key] = ListDicTwo[item.Key];
}
The final state of ListDicOne is:
("AABC", "oooo")
("ABCD", "WOW")
("EFGH", "test")
I hope you find this clarifying and useful.
** Update **
Considering a string-string list with non-unique keys:
private static List<Tuple<string, string>> ListOne = new List<Tuple<string, string>>();
private static List<Tuple<string, string>> ListTwo = new List<Tuple<string, string>>();
(...)
ListOne.Add(Tuple.Create("ABCD", ""));
ListOne.Add(Tuple.Create("ABCD", ""));
ListOne.Add(Tuple.Create("EFGH", "test"));
ListTwo.Add(Tuple.Create("AABC", "oooo"));
ListTwo.Add(Tuple.Create("ABCD", "WOW"));
ListTwo.Add(Tuple.Create("CCDD", "haha"));
ListTwo.Add(Tuple.Create("CCDD", "haha"));
foreach (var l2item in ListTwo)
{
for (int i = 0; i < ListOne.Count; i++)
{
if (ListOne[i].Item1 == l2item.Item1)
ListOne[i] = Tuple.Create(l2item.Item1, l2item.Item2);
}
}
Note 1: tuples are immutable, so you need to create a new one when changing Item2.
Note 2: You cannot use foreach when you need to alter the iterated list, therefore I used a for instead.
Note 3: If ListTwo happens to have a two different key-value combinations (supposedly won't happen), the second one will overwrite the first.
This is the end result with your test values:
("ABCD", "WOW")
("ABCD", "WOW")
("EFGH", "test")

Adding a key value pair in a dictionary inside a dictionary

I have a dictionary < string,object > which has a mapping of a string and a dictionary < string,int >. How do I add a key value pair in the inside dictionary < string ,int > ?
Dictionary <string,object> dict = new Dictionary <string,object>();
Dictionary <string,int> insideDict = new Dictionary <string,int>();
// ad some values in insideDict
dict.Add("blah",insideDict);
So now the dict has a dictionary mapped with a string.Now I want to separately add values to the insideDict.
I tried
dict["blah"].Add();
Where am I going wrong?
Do you mean something like this?
var collection = new Dictionary<string, Dictionary<string, int>>();
collection.Add("some key", new Dictionary<string, int>());
collection["some key"].Add("inner key", 0);
Something like below
Dictionary<string, object> dict = new Dictionary<string, object>();
dict.Add("1", new Dictionary<string, int>());
(OR) if you already have defined the inner dictionary then
Dictionary<string, object> dict = new Dictionary<string, object>();
Dictionary<string, int> innerdict = new Dictionary<string, int>();
dict.Add("1", innerdict); // added to outer dictionary
string key = "1";
((Dictionary<string, int>)dict[key]).Add("100", 100); // added to inner dictionary
Per your comment tried this but screwed up somewhere
You didn't got it cause of your below line where you forgot to cast the inner dictionary value to Dictionary<string, int> since your outer dictionary value is object. You should rather have your outer dictionary declared strongly typed.
dict.Add("blah",insideDict); //forgot casting here
Dictionary<string, Dictionary<string,TValue>> dic = new Dictionary<string, Dictionary<string,TValue>>();
Replace the TValue with your value type.

Get Values from dictionary present in List

I have a list like,
List<string> list = new List<string>();
list.Add("MEASUREMENT");
list.Add("TEST");
I have a dictionary like,
Dictionary<string, string> dict = new Dictionary<string, string>();
dict.Add("BPGA", "TEST");
dict.Add("PPPP", "TEST");
dict.Add("RM_1000", "MEASUREMENT");
dict.Add("RM_2000", "MEASUREMENT");
dict.Add("CDMA", "TEST");
dict.Add("X100", "XXX");
Now, I want to get all matched data from dictionary based on list.
Means, all data from list match with dict value then get new dictionary with following mathched values
Is there any way to achieve this by using lambda expression?
I want result like this.
Key Value
"BPGA", "TEST"
"PPPP", "TEST"
"RM_1000", "MEASUREMENT"
"RM_2000", "MEASUREMENT"
"CDMA", "TEST"
Thanks in advance!
You should be using the dictionary like it is intended to be used i.e. a common key with multiple values for example:
Dictionary<string, List<string>> dict = new Dictionary<string, List<string>>();
Then all you need to do when adding the values is:
dict.Add("TEST", new List<string>() { /*strings go in here*/ });
Then to get all the results from a key like:
List<string> testValues = dict["TEST"];
To make it safe however you should check that the key exists i.e.
if (dict.ContainsKey("TEST"))
{
//Get the values
}
Then to add values to a current key you go do something like:
dict["TEST"].Add("NewValue");
If you insist on keeping the same structure, although I do not recommend it, something like the following will work:
List<string> testKeys = new List<string>();
foreach (var pairs in dict)
{
if (pair.Value == "TEST")
{
testKeys.Add(pair.Key);
}
}
Or even the following LINQ statement:
List<string> testKeys = dict.Where(p => p.Value == "TEST").Select(p => p.Key).ToList();
For a generic query to find the ones from your list use:
List<string> values = dict.Where(p => list.Contains(p.Value)).ToList();

How to search in a dictionary?

I am trying to search in a dictionary.
I have 2 dictionaries:
Dictionary<int, string> dict = new Dictionary<int, string>()
Dictionary<int, int> temp = new Dictionary<int, int>()
then ive populated this dictionary with:
dict.Add(123, "");
dict.Add(124, ""); //and so on
then i want to loop though this dictionary and recall the key and add that to the other dictionary
for (int i = 0; i < dict.Count; i++)
{
if (dict[i] == "")
{
temp.Add(dict[dict.ElementAt(i).Key],0);
dict[dict.ElementAt(i).Value] = "Moved";
}
}
i shall be doing other things inside this forloop so i cannot change that to a foreach loop. I am trying to check if the value of the Dictionary dict is empty then take the Key and copy the key value to the temp dictionary, but i am getting errors.
Please help :)
the problem im trying to solve is that i want to be able to search the dict dictionary for for a value with "" and take the key and store it in another dictionary temp (which will later on hold a second value). i need to do this in a for-loop as i want to be able to go back by changing the value of i.
i want to be able to use i to select both the key and value from the dict dictionary.
The errors i was getting was simply converting from string to int, i cannot get it to even store the key from dict into an int variable.
You need to put a value in the temp dictionary. I chose 0.
Dictionary<int, string> dict = new Dictionary<int, string>();
Dictionary<int, int> temp = new Dictionary<int, int>();
dict.Add(123, "");
dict.Add(124, ""); //and so on
int[] keys = dict.Keys.ToArray();
for (int i = 0; i < dict.Count; i++)
{
if (dict[keys[i]] == "")
{
temp.Add(keys[i],0);
dict[keys[i]] = "Moved";
}
}
I think this is what you're looking for:
Dictionary<int, string> dict = new Dictionary<int, string>();
List<int> temp = new List<int>();
dict.Add(123, "");
dict.Add(124, ""); //and so on
foreach (int key in dict.Keys.ToList())
{
if (dict[key] == "")
{
temp.Add(key);
dict[key] = "Moved";
}
}
}
*
First, notice temp is a List, not a Dictionary, since you're just adding the keys, no key => value (this can be changed if you can better explain why you need this as a dictionary)...
Second, notice I used dict.Keys to get all the keys in the dictionary. I also used ToList() so it can work in the foreach loop...
are you getting a compile error for the dictionary definition
Dictionary<int, int> temp = new Dictionary<int, temp>(); // int, temp?
if so,
Dictionary<int, int> temp = new Dictionary<int, int>(); // int, int
?
or, you're getting an error with this:
temp.Add(dict[dict.ElementAt(i).Key]);
because you're adding just a key, with no value. it would be something like
temp.Add(i, dict[i]); ?
if you're just using temp to hold the key values, you don't want a Dictionary, you probably HashSet (only keys, no keys+values)
if you explain exactly what you're trying to solve, this is probably something you can do trivially with a single linq statement?
Why is temp a dictionary? I would use a List<int> with all keys of the dictionary with an empty(null?) value.
List<int> keysWithEmptyValuesInDictionary = dict
.Where(kvp => string.IsNullOrEmpty(kvp.Value))
.Select(kvp => kvp.Key)
.ToList();
foreach (int key in keysWithEmptyValuesInDictionary)
{
dict[key] = "moved";
}

Categories

Resources