list of dictionaries order by value C# - c#

How can I order by value in descending order following the dictionary list
List<Dictionary<int, int>> myList = new List<Dictionary<int, int>>();
Dictionary<int, int> obj = new Dictionary<int, int>();
obj.Add(1, 2);
myList.Add(obj);
myList.Add(obj);
Dictionary<int, int> obj2 = new Dictionary<int, int>();
obj2.Add(2, 4);
myList.Add(obj2);
Dictionary<int, int> obj3 = new Dictionary<int, int>();
obj3.Add(3, 3);
myList.Add(obj3);
myList.Add(obj3);
myList.Add(obj3);
expected output will be
[0][2,4],
[1][3,3],
[2][3,3],
[3][3,3],
[4][1,2],
[5][1,2]

you can do something like this
var orderedValues = myList
.SelectMany(x => x)
.OrderByDescending(x => x.Value)
.ToList();
and output the data
for (int i = 0; i < orderedValues.Count(); i++)
{
Console.WriteLine($"[{i}][{orderedValues[i].Key},{orderedValues[i].Value}]");
}

Related

Transform Dictionary<string, int> to Dictionary<int, List<string>>

Q How can I most efficiently convert a Dictionary<string, int> to a Dictionary<int, List<string>>?
Example
var input = new Dictionary<string, int>() { {"A", 1}, {"B", 1}, {"C", 2} ...
Dictionary<int, List<string>> result = Transform(input)
Assert.IsTrue(result, { {1, {"A", "B"}}, {2, {"C"}} ... });
Group the dictionary by values and map the group keys to list of keys:
input.GroupBy(x => x.Value).ToDictionary(x => x.Key, x => x.Select(_ => _.Key).ToList())
How about this?
var result =
dict.ToLookup(x => x.Value, x => x.Key)
.ToDictionary(y => y.Key, y => y.ToList());
Although I don't see why you couldn't just use the result from dict.ToLookup() without changing it to a dictionary, for example:
var dict = new Dictionary<string, int>
{
{"One", 1},
{"Two", 2},
{"1", 1},
{"TWO", 2},
{"ii", 2}
};
var test = dict.ToLookup(x => x.Value, x => x.Key);
Console.WriteLine(string.Join(", ", test[2])); // Prints: Two, TWO, ii
You can use Linq to achieve.
private static Dictionary<int, List<string>> Transform(Dictionary<string, int> input)
{
var result = new Dictionary<int, List<string>>();
foreach (var value in input.Select(x => x.Value).Distinct())
{
var lst = input.Where(x => x.Value == value).Select(x => x.Key).ToList();
result.Add(value, lst);
}
return result;
}

Dictionary<string, int> to List<Dictionary<string, int>> in c#

Is there a clean method to do this?
I tried
List<Dictionary<string, int>> myList = new List<Dictionary<string, int>>();
myList = myDict.ToList();
But that doesn't work, I'm looking for something similar to above if that is possible?
There are two statements in your question.
Assuming first is correct then do
myList.Add(myDict);
But if your second statement is correct then your first statement should be
List<KeyValuePair<string, int>> myList = new List<KeyValuePair<string, int>>();
Code:
Dictionary<string, int> myDict = new Dictionary<string, int>();
myDict.Add("1", 1);
myDict.Add("2", 2);
myDict.Add("3", 3);
myDict.Add("4", 4);
myDict.Add("5", 5);
List<Dictionary<string, int>> myList = new List<Dictionary<string, int>>();
myList.Add(myDict);
Something like this?
I think you need something like this:
Dictionary<int, string> myDict = new Dictionary<int, string>();
myDict.Add(1, "one");
myDict.Add(2, "two");
myDict.Add(3, "three");
List<KeyValuePair<int, string>> myList = myDict.ToList();
And retrieve data in this way:
// example get key and value
var myKey = myList[0].Key;
var myVal = myList[0].Value;

How to join two dictionaries?

I have two dictionaries. If the values in dict2 are same then we have to add the values for the matching keys from dict1 and generate a result in the result dictionary as given below.
**dict1** **dict2**
Id value Id value
24379 348 24379 270451
24368 348 24368 270451
24377 90 24377 270450
24366 90 24366 270450
24369 10 24369 270450
24300 25
Result:
24379 696
24368 696
24377 190
24366 190
24369 190
I have the following logic and would like to optimize this solution:
Dictionary<int, int> result = new Dictionary<int, int>();
foreach (int itemKey in dict1.keys)
{
result.add (itemKey, dict1.Where(a => dict2.ContainsKey(a.key)
&& dict2.ContiansKey(itemKey)
&& dict2[a.key] == dict2[itemKey])
.Sum(a => a.value);
}
You can do it in two steps:
Prepare a dictionary for looking up the value by dict2's value
Walk through dict1, and insert values from the look-up dictionary
Here is how you can do it:
var lookup = dict1
.Where(p => dict2.ContainsKey(p.Key))
.GroupBy(p => dict2[p.Key])
.ToDictionary(g => g.Key, g => g.Sum(p => p.Value));
var res = dict1.Keys
.Where(k => dict2.ContainsKey(k))
.ToDictionary(k => k, k => lookup[dict2[k]]);
Demo.
public static void DicAddTest()
{
Dictionary<int, int> dic1 = new Dictionary<int, int>() { {24379,348}, { 24368, 348 }, { 24377, 90 }, { 24366, 90 } };
Dictionary<int, int> dic2 = new Dictionary<int, int>() { { 24379, 270451 }, { 24368, 270451 }, { 24377, 270450 }, { 24366, 270450 } };
Dictionary<int, int> dicResult = DicAdd(dic1, dic2);
foreach (KeyValuePair<int, int> kvp in dicResult)
Debug.WriteLine("{0} {1}", kvp.Key, kvp.Value);
Debug.WriteLine("");
}
public static Dictionary<int, int> DicAdd(Dictionary<int, int> dic1, Dictionary<int, int> dic2)
{
Dictionary<int, int> dicResult = new Dictionary<int, int>(dic1);
foreach (int k in dic1.Keys.Where(x => dic2.Keys.Contains(x)))
dicResult[k] = dicResult[k] + dicResult[k];
return dicResult;
}
question is not clear
public static Dictionary<int, int> DicAdd2(Dictionary<int, int> dic1, Dictionary<int, int> dic2)
{
Dictionary<int, int> dicResult = new Dictionary<int, int>();
foreach (KeyValuePair<int, int> kvp in dic1.Where(x => dic2.Keys.Contains(x.Key)))
dicResult.Add(kvp.Key, 2 * kvp.Value);
return dicResult;
}
Perhaps it's easier to do like this, if you are not sure that dict1 and dict2 will have the same keys:
var result = new Dictionary<int, int>();
foreach(var kvp in dict1)
{
int value;
if(dict2.TryGetValue(kvp.Key, out value))
{
result[kvp.Key] = kvp.Value * 2;
}
}
This will only add values present in both dictionaries. If your Dictionary is very big, you could perhaps use a Parallel For, or consider use Hashtable instead.

How to get the value of an inner Dictionary?

Here is my dictionary.
var dic = new Dictionary<string, Dictionary<string, int>>();
I need to get the value of the int in the inner dictionary.
foreach (var country in dic)
{
output.AppendFormat("{0} (total population: {1})", country.Key, HERE);
}
Any help?
If you want a population sum ("total popuplation"), you can use:
var sum = country.Value.Values.Sum();
output.AppendFormat("{0} (total population: {1})", country.Key, sum);
This uses LINQ, so you are required to have
using System.Linq;
in your source file.
Try to run this sample in degugger:
var dic = new Dictionary<string, Dictionary<string, int>>();
var cities = new Dictionary<string, int>();
cities.Add("Kiev", 6000000);
cities.Add("Lviv", 4000000);
dic.Add("Ukraine", cities);
var totalPopulationByCountry = dic.ToDictionary(x => x.Key, y => y.Value.Values);
var sumPopulationByCountry = dic.ToDictionary(x => x.Key, y => y.Value.Values.Sum());
should be what you need

Simplest way to add all content of Dictionary<T1, T2> to another Dictionary<T1, T2> (equal types for key & value)?

Is there a simpler way to copy/add all content of source dictionary to destination Dictionary<T1, T2> object than using one of the two options in the sample below?
Dictionary<string, int> source = new Dictionary<string, int>(),
destination = new Dictionary<string, int>();
source.Add("Developers", 1);
source.Add("just", 2);
source.Add("wanna have", 3);
source.Add("FUN!", 4);
// Option 1 (feels like a hack):
//
source.All(delegate(KeyValuePair<string, int> p)
{
destination.Add(p.Key, p.Value);
return true;
});
// Option 2:
//
foreach (string k in source.Keys)
{
destination.Add(k, source[k]);
}
What I was looking for is something like .ForEach().
Yes, you can use the constructor:
Dictionary<string, int> destination = new Dictionary<string, int>(source);
If destination is already filled and you don't want to lose them as commented i'd use this:
foreach (var kv in source)
if (!destination.ContainsKey(kv.Key))
destination.Add(kv.Key, kv.Value);
You can use Concat:
Dictionary<string, int> dict1 = new Dictionary<string, int>();
dict1.Add("first", 1);
Dictionary<string, int> dict2 = new Dictionary<string, int>();
dict2.Add("second", 2);
dict2 = dict2.Concat(dict1).ToDictionary(k => k.Key, v => v.Value);
This of course doesn't really 'add' it to the dictionary, but replaces it by a new one. You can use Union to get rid of duplicates.
static void Main()
{
Dictionary<string, int> source = new Dictionary<string, int>();
Dictionary<string, int> destination = new Dictionary<string, int>();
destination.Add("Apple", 1);
destination.Add("Banana", 2);
foreach (var item in destination)
{
source.Add(item.Key, item.Value);
}
foreach (var item in destination)
{
Console.WriteLine("Key is {0} and value is {1}", item.Key, item.Value);
}
}

Categories

Resources