find all data from dictionary collection value to another dictionary collection key - c#

I have dictionary collection
{key -> string, value -> class}
and I have another dictionary collection
{key -> string, value -> string}
note : 2nd dictionary collection {key -> string, value -> string}.Value is 1st dictionary collection {key -> string, value -> class}.Key
So, I have To find All Data From 1st dictionary collection according to 2nd collection value.

class MyTest
{
public int myValue { get; set; }
}
Main()
{
Dictionary<string, string> First = new Dictionary<string, string>();
First.Add("dd", "test");
First.Add("ss", "test");
First.Add("tt", "test");
First.Add("aa", "test");
First.Add("mm", "test");
Dictionary<string, MyTest> Second = new Dictionary<string, MyTest>();
Second.Add("dd", new MyTest() { myValue = 123 });
Second.Add("oo", new MyTest() { myValue = 123 });
Second.Add("tt", new MyTest() { myValue = 123 });
Second.Add("aa", new MyTest() { myValue = 123 });
Second.Add("rr", new MyTest() { myValue = 123 });
var Final1 = First.Where(S => Second.Any(T => S.Key.Equals(T.Key)));
var Final2 = Second.Where(S => First.Any(T => S.Key.Equals(T.Key)));
Console.WriteLine("\nFirst\n");
foreach (var item in Final1)
{
Console.WriteLine(item.Key + "-" + item.Value);
}
Console.WriteLine("\nSecond\n");
foreach (var item in Final2)
{
Console.WriteLine(item.Key + "-" + item.Value.myValue);
}
}

From my understanding of your question you want to lookup the first dictionary based on a second dictionaries value.
public class Test
{
public string MyValue {get;set;}
}
Dictionary<string, Test> DictOne = new Dictionary<string, Test>();
Dictionary<string, string> DictTwo = new Dictionary<string, string>();
DictOne.Add("DictOneKeyOne", new Test() { MyValue = "DictOneValueOne" } );
DictTwo.Add("DictTwoKeyOne", "DictOneKeyOne");
Test ValueFromDictOne = DictOne.ContainsKey(DictTwo["DictTwoKeyOne"]) ? DictOne[DictTwo["DictTwoKeyOne"]] : null;

Related

Adding to reflected Dictionaries

I have a legacy class that looks like this:
public class LegacyBusinessObject
{
....(100 similar fields in total)
public Dictionary<string, string> SomeBusinessValue1 = new Dictionary<string, string>();
public Dictionary<string, long> SomeBusinessValue2 = new Dictionary<string, long>();
public Dictionary<string, decimal> SomeBusinessValue3 = new Dictionary<string, decimal>();
....
}
whereas the string key denominates the provider this value came from.
So for context: "SomeBusinessValue1" could be a weight measurement, that differs depending on the lab that did it.
I want to merge several of these monsters into one object using reflection:
public LegacyBusinessObject Merge(Dictionary<string, LegacyBusinessObject> objects)
{
var result = new LegacyBusinessObject();
//Loop through all the business object's fields
foreach (var prop in typeof(LegacyBusinessObject).GetFields())
{
//Second loop through all the individual objects from different providers
foreach (var ep in objects)
{
//Here I would need to test for all possivle value types that could
//be in the dictionary: <string, string>, <string, long>...
//then cast to it and invoke the Add method like this:
var propDictionary = prop.GetValue(result) as Dictionary<string, string>;
propDictionary.Add(ep.Key, ep.Value);
}
}
return result;
}
Now this approach requires me to do a lot of clumsy casts for propDictionary. (I also tried consctructing the matching keyvaluepair<,> and an Activator to instance it; but i can't find a way to add this to another dictionary)
Can you think of a better way to perform this merge, that takes arbitrary dictionary value types?
Some more context:
I am getting a LegacyBusinessObject Obj1 with data from Lab A and Lab B that is stored in the dictionaries. No I am cleaning up the database and find out that another LegacyBusinessObject Obj2 has Data from Lab C and Lab D. As it turns out there was a mistake during ingestion and Obj1 and Obj2 are for the same product and have wrongfully been stored in two different LegacyBusinessObjects. I now want to merge the data to get a new LegacyBusinessObject with Data from Lab A through D
Quite unclear what you are exactly asking, but:
public static LegacyBusinessObject Merge(Dictionary<string, LegacyBusinessObject> objects)
{
var result = new LegacyBusinessObject();
foreach (var prop in typeof(LegacyBusinessObject).GetFields())
{
var propDictionaryNew = (IDictionary)prop.GetValue(result);
foreach (var dict in objects)
{
var propDictionaryOld = (IDictionary)prop.GetValue(dict.Value);
foreach (DictionaryEntry de in propDictionaryOld)
{
propDictionaryNew[de.Key] = de.Value;
// Or:
//((IDictionary)result).Add(de.Key, de.Value);
// But be aware of exceptions if de.Key is present in multiple dictionaries
}
}
}
return result;
}
and then, to test it:
var lbo1 = new LegacyBusinessObject
{
SomeBusinessValue1 = new Dictionary<string, string> { { "A1", "A2" }, { "B1", "B2" } },
SomeBusinessValue2 = new Dictionary<string, long> { { "C1", 1 }, { "D1", 2 } },
SomeBusinessValue3 = new Dictionary<string, decimal> { { "E1", 3 }, { "F1", 4 } },
};
var lbo2 = new LegacyBusinessObject
{
SomeBusinessValue1 = new Dictionary<string, string> { { "G1", "G2" }, { "H1", "H2" } },
SomeBusinessValue2 = new Dictionary<string, long> { { "I1", 5 }, { "J1", 6 } },
SomeBusinessValue3 = new Dictionary<string, decimal> { { "K1", 7 }, { "L1", 8 } },
};
var result = Merge(new Dictionary<string, LegacyBusinessObject> { { "X", lbo1 }, { "Y", lbo2 } });
I'm cheating a little here... Dictionary<,> implements the pre-generics interface IDictionary (that is different from IDictionary<,>) that uses object as key and value. In this way I don't have to support the different value types. When using reflection with generic collections, a good trick is to see if the non-generic interfaces are enough to do what you need (because they are much easier to handle with reflection).

How to get key value based on id from list of dictionaries?

This is my code
public class model
{
public model();
public List<Dictionary<string, string>> Data { get; set; }
}
List<Dictionary<string,string>> data1;
var data1 = await get<model>();
data1[0]=[0][{id,101}]
[1][{name,one}]
data1[1]=[0][{id,102}]
[1][{name,two}]
data1[2]=[0][{id,103}]
[1][{name,three}]
In the code i have a list of dictionaries with id and name keys. now i have id=102 search in list of dictionaries and get name value related on id using linq query.
var name = data1.First(d => d["id"] == "102")["name"];
You find the first list element where the key "id" maps to value "102", and then get the value for key "name".
Try this
List<Dictionary<string, string>> data1 = new List<Dictionary<string, string>>();
Dictionary<string, string> dic1 = new Dictionary<string, string>();
dic1.Add("101", "one");
dic1.Add("102", "two");
data1.Add(dic1);
dic1 = new Dictionary<string, string>();
dic1.Add("201", "2one");
dic1.Add("202", "2two");
data1.Add(dic1);
dic1 = new Dictionary<string, string>();
dic1.Add("301", "3one");
dic1.Add("302", "3two");
data1.Add(dic1);
//try your values here
var id = "201";
var s=data1.Where(c => c.Keys.Contains(id)).Select(c => c.Keys.Where(p => p == id).Select(p => c[p]).FirstOrDefault()).FirstOrDefault();
Console.WriteLine(s);

Sorting a list of dictionaries based on a key

I have a list of dictionaries which contains student data
It is something like
List<Dictionary<string, object>> students = new List<Dictionary<string, object>>();
Dictionary<string, object> std1 = new Dictionary<string, object>();
std1["name"] = "sai";
std1["age"] = 22;
std1["gender"] = "male";
students.Add(std1);
Dictionary<string, object> std2 = new Dictionary<string, object>();
std2["name"] = "Julia";
std2["gender"] = "female";
students.Add(std2);
Dictionary<string, object> std3 = new Dictionary<string, object>();
std3 ["name"] = "sunny";
std3 ["age"] = 23;
students.Add(std3);
And I want to sort the list of students based on either name, age or gender, I am trying something like this:
var ordered = students.OrderBy(x => x["name"]);
If I try with either age or gender it is returning an error that key is not found, as std2 doesn't have age and std3 doesn't have gender.
I need all the records even it doesn't contain the value for sorted key, Any way to solve this problem, Thanks in advance.
It is better to create a class like this:
public class YourClass
{
public string Name { get; set; }
public int Age { get; set; }
public string Gender { get; set; }
}
Then:
List<YourClass> students = new List<YourClass>();
YourClass std1 = new YourClass();
std1.Name = "sai";
std1.Age = 22;
std1.Gender = "male";
students.Add(std1);
yourClass std2 = new yourClass();
std2.Name = "Julia";
std2.Gender = "female";
students.Add(std2);
yourClass std3 = new yourClass();
std3.Name = "sunny";
std3.Age = 23;
students.Add(std3);
var ordered = students.OrderBy(x => x.Name);
This arrangement stores the same data you had in multiple dictionaries. However, it's far more clear and understandable.
If you want to sort by a key that is not present in all of the dictionaries, you'll need to return a default value instead, for example 0.
var ordered = students.OrderBy(dict =>
{
string name;
if (!dict.TryGetValue("name", out name))
return "";
return name;
});
Shorter version using the conditional ternary operator:
var ordered = students.OrderBy(dict =>
{
string name;
return dict.TryGetValue("name", out name) ? name : 0;
});
I use Dictionary.TryGetValue(...) which returns a bool depicting whether the key was found in the dictionary and its value returned.
You can solve this problem by supplying a GetOptional method that returns some default object in situations when the dictionary does not have a specific key:
V GetOptional<K,V>(IDictionary<K,V> d, K key, V absent) {
V res;
return d.TryGetValue(key, out res) ? res : absent;
}
Now you can sort like this:
var byName = students.OrderBy(x => GetOptional<string,object>(x, "name", "----"));
var byAge = students.OrderBy(x => GetOptional<string,object>(x, "age", "10000"));
Note: Using dictionaries like this gives you flexibility at the expense of clarity. It is usually better to define a special Student type, rather than using a universal collection of key-value pairs.

How to Add an item to ArrayList and Dictionary using reflection

public class MyClass
{
public MyClass()
{
myDictionary = new Dictionary<string, string>();
myArray = new List<int>();
}
private Dictionary<string, string> myDictionary;
public Dictionary<string, string> MyDictionary
{
get { return myDictionary; }
}
private List<int> myArray;
public List<int> MyArray
{
get { return myArray; }
}
}
static void Main(string[] args)
{
var model = new MyClass();
Type t = model.GetType();
System.Reflection.PropertyInfo[] properties = t.GetProperties();
//Add items to MyArray and MyDictionary in this model According to the properties using reflection
}
I want to add items to MyArray and MyDictionary in this model According to the properties using reflection.
Thank you for your help !
var dictProp = properties.Single(t => t.Name = "MyDictionary");
var myDict = (Dictionary<string,string>)dictProp.GetValue(model, null);
myDict.Add("MyKey", "MyValue");
To add an Item to a Generic.List<T> you use the Add method
Example:
MyArray.Add(1);
For Generic.Dictonary<T> you also use the Add method, but supply 2 values, Key and Value
MyDictionary.Add("MyKey", "MyValue");
So you can just loop though your PropertyInfo[] and add whatever you need to your List<T> or Dictionary<T>
foreach(var prop in properties )
{
MyArray.Add(a number from somewhere);
MyDictionary("some key", "some value");
}

copy dictionary containing object to an array of objects c#

I have a Dictionary like Dictionary<string,Object>,is there any method of converting the Dictionary to an array of objects,where the class of the object will contain two members-one of which will be the string and the other will be the Object stored as the value-pair in the dictionary.Please help!!!..
Dictionary<TKey, TValue> implements IEnumerable<T> where T is KeyValuePair<TKey, TValue>. To flatten this to an array all that is necessary is to call IEnuemrable<T>.ToArray as such:
Dictionary<string, int> dict = new Dictionary<string, int>() { { "Key1", 0 }, { "Key2", 1 } };
var kvArray = dict.ToArray();
kvArray will then be an array objects that reference the keys and values of each element in dict as two separate members of the same object.
Your question is a bit ambiguous though, perhaps further explanation would help us figure out a more appropriate solution.
Re your comment, LINQ is good for that:
Dictionary<string, int[]> dict = new Dictionary<string, int[]>() { { "Key1", new int[] { 0, 1, 2 } }, { "Key2", new int[] { 4, 5, 6 } } };
var pairs = dict.SelectMany(pair => pair.Value
.Select(v =>
new {
Key = pair.Key,
Value = v
}
)
);
Given a class:
class ClassA
{
string CustomerId { get; set; }
PatientRecords[] Records { get; set; }
public ClassA(string name, PatientRecords[] records)
{
Name = name;
Records = records;
}
}
I'm assuming that CollectionOfPatientRecords implements IEnumberable:
var dict = new Dictionary<string, CollectionOfPatientRecords> ( ... );
Then to get your array of ClassA with the right values:
dict.Select(kv => new ClassA(kv.Key, kv.Value.ToArray())).ToArray();

Categories