Get common keys and common values of two dictionaries - c#

Hi I have two dictionaries of next type:
SortedDictionary<string, ClusterPatternCommonMetadata> PatternMetaData { get; set; }
The ClusterPatternCommonMetadata object looks like:
int ChunkQuantity { get; set; }
SortedDictionary<int, int> ChunkOccurrences { get; set; }
First I need the way to find keys of PatternMetaData that is exists in two dictionaries. I find this way:
List<string> commonKeysString=
vector.PatternMetaData.Keys.Intersect(currentFindingVector.PatternMetaData.Keys)
Then I need to find common values of the founded keys...
Is there is the fast way (lambda, linq, etc) in order to do such operation
Thanks

This is called intersection.
You can get the keys using
var data = dictionary1.Keys.Intersect(dictionary2.Keys)
If you want to find equal keys and values that are contained within both dictionaries then just
var equalDictionarys = dictionary1.Intersect(dictionary2);

You can also get the whole Dictionary items which have common keys:
var commonDictionaryItems = Dic1.Where(d => Dic2.ContainsKey(d.Key)).ToList();

Related

Indexes that correspond to each other in two Lists

I have two Lists:
List<string> names = new List<string>();
List<int> goals = new List<int>();
One of them is a string List while the other one is a int List. I add some numbers in the second List, and then I get the biggest number in the List. This works.
Now I need to type some names in the console and after each name I need to type a certain number and this repeats to whenever I want.
How do I get the index of the biggest number in the second list and to print it alongside the name that actually have "scored" that biggest number? I want to get the index from the first string List that corresponds to the index of the biggest number in the second List. Is there a way that I can do it?
In your case, "Name" and "Goals" relate to each other. Someone or something with a "Name" has obviously attached to them a number of "Goals". So, let's reflect this relation in a class:
public class StatisticsItem
{
// Properties here
public string Name {get; set;}
public int Goals {get; set;}
}
You then can create new instances of that class like so:
var item = new StatisticsItem() { Name = "Marc", Goals = 5 };
and you can put those in a list:
var myList = new List<StatisticsItem>();
myList.Add(item);
Find your champion:
using System.Linq;
// ...
Console.WriteLine("Goalie King: {0}", myList.MaxBy(x => x.Goals).Name);
See in action: https://dotnetfiddle.net/I9w5u7
To be a bit more clean, you could of course use a constructor:
public class StatisticsItem
{
// Properties here
public string Name {get; set;}
public int Goals {get; set;}
public StatisticsItem(string name, int goals)
{
Name = name;
Goals = goals
}
}
// and then create instances like so:
var item = new StatisticsItem("Marc", 5);
Can't comment so i will add my opinion here. Fildor suggested 1 list with 2 properties which should cover your case. I would say also check if a dictionary<string, int> or a dictionary<string, List<int>> is a better fit instead of a list.
Keep in mind for a dictionary to work the key (name in your case) must be unique. If not discard this answer

Except in LINQ C#

I have to lists. One that contains all the valid chapter codes(chpt_cd) and their associated appl src codes. i.e the list is
List<ChapterCodeValidationOutput>
The base model class is
public class ChapterCodeValidationOutput
{
public string chpt_cd { get; set; }
public string appl_src_cd { get; set; }
}
The list sample data is ..
chpt_cd aapl_src_cd
------- -----------
07038 C062
07038 C062
06206 C191
And another list contains invalid chapter codes only.
List<string>
only.
And it's sample data is '06206'
I have to find the associated appl_src_cd of the invalid chapter codes list i.e. 'C191' and so on . The returned should be a list only.
Except will not help you in this case.
Assuming that these are the lists:
List<ChapterCodeValidationOutput> list1 = ...
List<string> list2 = ...
Then you can create a lookup from the first list for fast lookup like this:
var lookup = list1.ToLookup(x => x.chpt_cd, x => x.appl_src_cd);
And then use it like this to get the list of corresponding codes:
var result = list2.Select(x => lookup[x].First()).ToList();
I am assuming (since you mentioned in the comments), that if there are duplicate chpt_cd values, the corresponding appl_src_cd values will be equal.

Usage of Dictionaries in C#

I'm an old, old programmer so I'm very used to abuse Arrays but I will need to start using dictionaries since they can dynamically expand and Arrays can't.
Now... I need to populate values for a solar system where each body in that solar system have perhaps about 20-30 different values.
My intention was to use a dictionary where each body has it's own unique Key and a value, such as...
Dictionary<int,string> BodyName = new Dictionary<int,string>()
Dictionary<int,int> BodySize = new Dictionary<int,int>()
Dictionary<int,int> BodyX = new Dictionary<int,int>()
Dictionary<int,int> BodyY = new Dictionary<int,int>()
Dictionary<int,int> BodyVelocity = new Dictionary<int,int>()
etc...
my question is what's the best way to go about to retrieve the values from all these dictionaries?
The key for each 'body" is the same in each dictionary. I know I can do this with lots of loops, but that seems quite wasteful on CPU cycles and that is a bad thing for me.
I also considered Dictionary,List but that has other issues I don't particularly like.
Create a composite type, and use that.
Sticking with Dictionaries is suitable if the key is a unique identifier - a planet ID? a planet name? - that must be used to look up the data. Don't forget that iteration over dictionaries is non-deterministic.
Dictionary<int,PlanetaryBody> Bodies = new Dictionary<int,PlanetaryBody>()
On the other hand, a sequence is suitable if the planets are only iterated (or accessed by positional indices). In this case, using a List often works well.
List<PlanetaryBody> Bodies = new List<PlanetaryBody>();
// Unlike arrays, Lists grows automatically! :D
Bodies.Add(new PlanetaryBody { .. });
(I very seldom choose an array over a List - it's better sometimes, but not often.)
The composite type (i.e. class) is used to group the different attributes into a larger concept or classification group:
class PlanetaryBody {
public string Name { get; set; }
public double Mass { get; set; }
// etc.
}
Just use a class for that.
public class Planet {
public int Id { get; set; }
public string Name { get; set; }
public int Size { get; set; }
// and so on for each property of whatever type you need.
}
When you need a new Planet just new up:
var planet = new Planet();
planet.Name = "Saturn";
// again finish populating the properties.
To add it to a list:
var list = new List<Planet>();
list.Add(planet);
// adding the planet you created above.
Then look into manipulating lists and so on using LINQ

What I should use to store a list of assosiated values to be able to retrieve, modify and save one of the elements

I am new to C# and I do not know how to do this
I have a set of associated values
dateValue (string)
valueOne (decimal)
valueTwo (decimal)
I need to be able to pick up the values by a certain date (I could change the dateValue to datetime) and save all the values after modify the valueOne and valueTwo
Should I create a list of objects and loop all the list searching for the proper dateValue which valueOne and valueTwo I want to modify?
What will be the best solution
Create a class, instantiate all the values and then add them to a list?
How could I search for an specific date?
It sounds like a Dictionary may be what you are looking for. A dictionary is a means of storing a Key/value pair and allowing fast and easy lookup of items by key. The key will be dateValue. The Value of the dictionary might be a class that contains valueOne and valueTwo. For example:
var dictionary = new Dictionary<string, Values>();
//Add an item to the dictionary
dictionary.Add("thekey", new Values {ValueOne = 1, ValueTwo = 2});
//Get the item out of the dictionary by key
var values = dictionary["thekey"];
//Update the value of ValueOne for "thekey"
values.ValueOne = 7;
//Print the new value
Console.WriteLine(dictionary["thekey"].ValueOne);
And the class:
public class Values
{
public decimal ValueOne { get; set; }
public decimal ValueTwo { get; set; }
}
As an aside, why not storedateValue as a DateTime rather than a string? This allows you to to have access to various APIs for working with date and time, such as formatting it for display, arithmetic, etc.
In object-oriented programming, you should represent your associated values with a class:
public class MyAssociatedValues // come up with a better name
{
public DateTime Date{get;set;}
public decimal Value1{get;set;} // needs a better name
public decimal Value2{get;set;} // ditto
}
Once you are representing your collection as an IEnumerable<MyAssociatedValues> (this could be a List, an array, or a number of other structures that implement IEnumerable<>), you can easily create a Dictionary to key these values based on their date.
var valuesByDate = values.ToDictionary(v => v.Date);
For easy retrieval by dateValue you could either use a Dictionary with a Tuple containing the two values
Dictionary<string, Tuple<string, string>>
or a Lookup, which is basically a Dictionary that can store a collection of values per key.
I would use a Dictionary to map the DateTime to a structure that contains valueOne and valueTwo.
Something like:
struct Data
{
public decimal valueOne { get; set; }
public decimal valueTwo { get; set; }
}
Dictionary<DateTime, Data> map = new Dictionary<DateTime, Data>();
void addToMap(DateTime dt, decimal one, decimal two)
{
map[dt] = new Data() { valueOne = one, valueTwo = two };
}
Firstly, I would create a class (POCO) instead of a struct unless you have a good reason for a struct.
public class TheClass
{
public DateTime TheDate { get; set; }
public decimal ValueOne { get; set; }
public decimal ValueTwo { get; set; }
}
Secondly, I would store them in any data structure that implements IEnumerable (collection-type) that makes sense. The one that doesn't seem to make sense to me is the one that everyone is suggesting (Dictionary) because it is very much possible that you have 2 objects with the same datetime, so why everyone is suggesting a dictionary baffles me. The only thing I can think of is that they are assuming you only have one pair of values per datetime.
Thirdly, use LINQ to enumerate over the sub-list based on your query.
foreach (var obj in myCollection.Where(item => item.TheDate == requestedDate))
{
//Do whatever you need to do to each enumerated item.
}
Alternatively, if you really want to use the Dictionary instead of LINQ you could create an IDictionary<DateTime, IEnumerable<TheClass>> which means you are caching the collection as the value in the Dictionary.
foreach (var obj in myDictionary[requestedDate])
{
//Do whatever you need to do to each enumerated item.
}

Binding a Dictionary to the DataGridView in C#?

I have a dictionary item as below
Dictionary<string, List<StrikePrice>>
where
public class StrikePrice
{
public string Strike { get; private set; }
public string Price { get; private set; }
public StrikePrice(string strike, string price)
{
Strike = strike;
Price = price;
}
}
and I wish to assign this dictionary to the DataGridView
this.dataGridViewTest.DataSource = listSmiles;
I understand that a dictionary can't be assigned to the the DataSource as this doesn't derive from the IList interface.
Is there any way I can assign this dictionary element to the datagrid?
I know this is a bit old, but perhaps it will help someone. This one line solution worked for me
gridTAV.DataSource = dTAV.Values.ToList<TotalAccountValue>();
gridTAV is a DataGridView. dTAV is a Dictionary. The key is a date (not important), and the value is a class.
Dictionary<DateTime, TotalAccountValue> dTAV = new Dictionary<DateTime, TotalAccountValue>();
Since the value was a class the "ToArray()" method did not work for me, since it didn't "unpack" the class properties.
Note that this does not place the KEY in the grid, but I didn't really need that.
Yes ,by Calling ToArray of Dictionary
var g = this.dataGridView1;
var s = new Dictionary<string, string>();
s.Add("1", "Test1");
s.Add("2", "Test2");
s.Add("3", "Test3");
g.DataSource = s.ToArray();
Have you tried using the Values property of the Dictionary?
this.dataGridViewTest.DataSource = listSmiles.Values.ToList();
If the question relates to WPF or silverlight, this article gives a solution.
I've been using it and it performs well, even for large numbers of columns.

Categories