How to get value from Dictionary<string,object> - c#

I have a dictionary for which I want to retrieve results matching to those of list
here is what I have done so far
Dictionary<string, Dictionary<string, int>> SomeDictionary = new Dictionary<string, Dictionary<string, int>>();
List<int> MyList = new List<int>()
{
2,3,4,5
};
Dictionary<string, int> internalDictionary = new Dictionary<string, int>();
internalDictionary.Add("two", 2);
internalDictionary.Add("three", 3);
internalDictionary.Add("four", 4);
internalDictionary.Add("five", 5);
Dictionary<string, int> AnotherDictionary = new Dictionary<string, int>();
AnotherDictionary.Add("six", 6);
AnotherDictionary.Add("three", 3);
AnotherDictionary.Add("seven", 7);
SomeDictionary.Add("Dictionary1", internalDictionary);
SomeDictionary.Add("Dictionary2", AnotherDictionary);
var res = from l in MyList
select(from q in
(from p in
(from s in SomeDictionary
select s)
select p) where q.Value.Equals(l) select q);
The value returned is null. what am i Missing ?
I need matching KeyValuePair where value matches internal dictionary values.

Explanation:
Select Many to combine all internal dictionaries into All In One dictionary.
List and SelectMany are IEnumerable. So join is possible between to IEnumerable objects.
However, List contains string value while IEnumerable object returned from SelectMany has integer value.
So created inner join query with string and integer value after converting integer to string. Refer screencast that might be required output
Screen cast showing working code
This Linq snippet may be helpful:
var allinone = (from l in MyList
join d in SomeDictionary.SelectMany(s => s.Value) on l equals d.Value
select d);

Try this:
var res = from l in MyList
from q in SomeDictionary
from w in q.Value
where w.Value == l
select w;
I get this:

Related

Sum on a dynamic list that has ExpandoObject as items

I have a dynamic list with ExpandoObject as items :
List<dynamic> list = new List<dynamic>();
foreach (...)
{
var dynamicObject = new ExpandoObject() as IDictionary<string, Object>;
...
list.Add(dynamicObject);
}
How can I use .Sum() on a dynamic list ? I know the names of the properties
of that list , but Sum() does not take a string as argument .
Thanks
Assuming you have list like this:
var list = new List<dynamic>
{
new ExpandoObject(),
new ExpandoObject(),
new ExpandoObject(),
};
list[0].Foo = 1;
list[1].Foo = 2;
list[2].Foo = 3;
you can use ExpandoObject's properties as regular properties, if their names are known at compile-time:
var sum1 = list
.Sum(item => item.Foo);
or use dictionary syntax, if property names are known at run-time only:
var sum2 = list
.Sum(item => (int)((IDictionary<string, object>)item)["Foo"]);
You can use Sum(Func<TSource, int> selector)
For you example :
var values = new int[] {1, 2, 3, 4, 5};
List<dynamic> list = new List<dynamic>();
foreach (var value in values)
{
var dynamicObject = new ExpandoObject() as IDictionary<string, Object>;
dynamicObject[value.ToString()] = value;
list.Add(dynamicObject);
}
// Kind of ugly as cast but otherwise it has trouble to find the Count property
var result = list.Sum(x => (x as IDictionary<string, Object>).Count);
Console.WriteLine("Result: {0}", result);
Console.ReadLine();
To my mind you could try this :
var listSum = list.Sum(item => item.GetType().GetProperty("propertyName").GetValue());
I called list the list on which you want to call the Sum method.
Let me know if the result is what you want.

C# LINQ converting a query to dictionary

A C# converting a query to dictionary:
public class myClass
{
public int my_id;
public Dictionary<string, Dictionary<string, string[]>> myDict;
}
Dictionary<string, myClass> dataDict;
Dictionary<int, Dictionary<string, myClass>> query = (from happen in dataDict
group happen by happen.Value.my_id into g
select g).ToDictionary( ?? );
I do not know what I should put in ( ?? ).
Any help would be appreciated.
Try this:
var query = (from happen in dataDict
group happen by happen.Value.my_id into g select g)
.ToDictionary(g => g.Key, g => g.ToDictionary(x => x.Key, x => x.Value));

Transform a DataTable with a single column to a Dictionary where the index is the key

Simple question. I have a Dictionary<int, double> that I wish to populate from the columns DataTable. So for a DataTable with a single column:
23.9
39009.0
32.99
12.1
I want a Dictionary<int, double> with
{ 1, 23.9 },
{ 2, 39009.0 },
{ 3, 32.99 },
{ 4, 12.1 }
where the key is auto-incrementing. To do this I have written some basic code:
Dictionary<int, double> d = new Dictionary<int, double>();
List<double> tmp = dataTable.AsEnumerable()
.Select(c => Double.Parse(c[i].ToString())).ToList();
int index = 1;
foreach (var j in tmp)
d.Add(index++, j);
Can I do this with LINQ with a single query? I am not a LINQ fan-boy, who likes to write it for the sake of it, but I do like to better my LINQ skills and I could not seem to work out a way to do this using a single LINQ query although it is probably possible.
Thanks for your time.
Can I do this with LINQ with a single query?
Yes
Dictionary<int, double> dict = dataTable.AsEnumerable()
.Select((row, index) => new { row, index })
.ToDictionary(x=> x.index + 1, x=> x.row.Field<double>(0));
Some might find this simpler...
int index = 1;
Dictionary<int, double> dict = dataTable.AsEnumerable().ToDictionary(x=>index++, x => x);
Replace x => x with however you go from your elements to the double value required.
(eg x => x.row.Field<double>(0) if it is a datatable with one column)
You could try the following:
d = tmp.Select( ( x, i ) => new { Value = x, Index = i } ).ToDictionary( pair => pair.Index, pair => pair.Value );

How to get a Lookup from nested dictionaries

I have a nested dictionary from which I want to derive a Lookup. Example data of the dictionary is following:
var binary_transaction_model = new Dictionary<string, Dictionary<string, bool>>();
binary_transaction_model.Add("123", new Dictionary<string, bool>(){{"829L", false},{"830L", true}});
binary_transaction_model.Add("456", new Dictionary<string, bool>(){{"829L", true},{"830L", false}});
binary_transaction_model.Add("789", new Dictionary<string, bool>(){{"829L", true},{"830L", true}});
This LINQ statement is working:
var cols = from a in binary_transaction_model
from b in a.Value
where b.Value == true
group a.Key by b.Key;
It gives me an IEnumerable<IGrouping<String,String>>. For lookup purposes I need this result as a Lookup data structure. How can I do this? How should a ToLookup() signature look like? (Edit: I want to have a Lookup<String,String>.)
This should work:
var cols = (from a in binary_transaction_model
from b in a.Value
where b.Value == true
select new { aKey = a.Key, bKey = b.Key })
.ToLookup(x => x.bKey, x => x.aKey);

Combining Dictionary<A,B> + Dictionary<B,C> to create Dictionary<A,C>

Any cool quick ways to take two dictionaries to create a third that maps the key of the first to the value of the second in an inner-join style?
Dictionary<A,B> dic1 = new Dictionary<A,B> {{a1,b1},{a2,b2},{a3,b3}};
Dictionary<B,C> dic2 = new Dictionary<B,C> {{b1,c1},{b2,c2},{b4,c4}};
Dictionary<A,C> dic3 = SomeFunction(dic1,dic2);
// dic3 = {{a1,c1},{a2,c2}}
You could do something like this to join on the inner value
Dictionary<int, string> first = new Dictionary<int, string> { {1, "hello"}, {2, "world"}};
Dictionary<string, bool> second =
new Dictionary<string, bool> { { "hello", true }, {"world", false}};
var result = (from f in first
join s in second on f.Value equals s.Key
select new { f.Key, s.Value }).ToDictionary(x => x.Key, y => y.Value);
If you dump out result you'll see it is a Dictionary with the value {1: true, 2: false}
try this -
Dictionary<string, string> a, b, c;
//code to initialize the 3 dictionaries. a,b are original dictionaries and c is the new dictionary
c = ( from ak in a.Keys
where b.ContainsKey( ak )
select new KeyValuePair<string, string>( ak, b[ ak ] ) ).ToDictionary( d => d.Key, d=> d.Value );
Maybe something with ToDictionary
dic1.Where(d1=>dic2.ContainsKey(d1.Value)).ToDictionary(d1=>d1.Key,d1=>dic2[d1.Value]);
Dictionary<int, string> dic1 = new Dictionary<int,string>();
Dictionary<string, decimal> dic2 = new Dictionary<string,decimal>();
dic1.Add(1, "one");
dic1.Add(2, "two");
dic1.Add(3, "three");
dic1.Add(4, "four");
dic1.Add(5, "five");
dic2.Add("one",1.0m);
dic2.Add("two", 2.0m);
dic2.Add("three", 3.0m);
dic2.Add("four", 4.0m);
dic2.Add("five", 5.0m);
Dictionary<int, decimal> result = (from d1 in dic1
from d2 in dic2
where d1.Value == d2.Key
select new { d1.Key, d2.Value }).ToDictionary(p=>p.Key, p=>p.Value);
public Dictionary<A,C> SomeFunction(dic1, dic2)
{
var dic3 = new Dictionary<A,C>();
foreach (var item in dic1)
{
var item2 = dic2.Where(m=>m.Key == item.Value).FirstOrDefault();
if (item2 != null)
{
dic3.Add(item.Key, item2.Value);
}
}
return dic3
}
I believe this will work for what you want
public IDictionary<A, C> SomeFunction<A, B, C>(IDictionary<A, B> dic1, IDictionary<B, C> dic2)
{
var dic3 = new Dictionary<A, C>();
foreach (var item in dic1)
{
var a = item.Key;
var b = item.Value;
if (dic2.ContainsKey(b))
{
var c = dic2[b];
dic3.Add(a, c);
}
}
return dic3;
}
Handles the case of dic2 not containing keys corresponding to dic1s value without fake null values being stored, and IMO is pretty clear. I do like some LINQ, but I thought I'd give a procedural answer for once...
The simplest solution:
var dict3 = dict1.ToDictionary(p => p.Key, p => dict2[p.Value]);

Categories

Resources