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
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).
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);
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.
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");
}
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();