How do I iterate over a hashset of dictionaries - c#

Apologies in advance; I am on day 3 of trying to learn C#.
I am instructed to build a hashset of dictionaries; no problem. I see that that has been built. I now need to iterate over the hashset and copy the entries to a new list if the dictionary's key != a particular string. Could someone kindly explain the proper syntax for achieving this seemingly simple task?
var goodSongs = new List<Dictionary<string,string>>();
var allSongs = new HashSet<Dictionary<string, string>>();
Dictionary<string, string> meatloaf = new Dictionary<string, string>();
meatloaf.Add("Meatloaf", "Paradise By The Dashboard Light");
Dictionary<string, string> aerosmith = new Dictionary<string,string>();
aerosmith.Add("Aerosmith", "Cryin'");
Dictionary<string, string> nickelback = new Dictionary<string, string>();
nickelback.Add("Nickelback", "Rockstar");
allSongs.Add(nickelback);
allSongs.Add(aerosmith);
allSongs.Add(meatloaf);
//foreach loop to iterate dictionaries goes here
Goal - To get unstuck, hope to learn C#, and decide if I want to keep going down this rabbit hole. Thanks to all.

Here is an example of how to iterate through the hashset and then the dictionary:
var all = new HashSet<Dictionary<string, string>>();
Dictionary<string, string> newDict = new Dictionary<string, string>();
newDict.Add("M", "T");
all.Add(newDict);
foreach(Dictionary<string,string> dict in all)
{
foreach(KeyValuePair<string,string> pair in dict)
{
string key = pair.Key;
string value = pair.Value;
}
}

Related

What keys/values do I add to the dictionary for the TeamProject capabilities property?

I am having difficulty figuring out how to set the Capabilities property for Microsoft.TeamFoundation.Core.WebApi.TeamProject. It expects a Dictionary<string, Dictionary<string, string>>, but I have no idea what the keys/values would look like. I need to set the "Version Control" and "Work Item Process". This is what I have so far.
var teamProject = new TeamProject {
Description = projectDescription,
Name = ProjectName,
Visibility = ProjectVisibility.Private,
//How to set this to "Version Control": Git, and "Work Item Process": Agile
Capabilities = new Dictionary<string, Dictionary<string, string>>()
};
I know there are a few HttpClients in Microsoft.TeamFoundation.Core.WebApi, but which client would give me a list of "Version Control" methods and "Work Item Process" methods. How would I set them as a Dictionary<string, Dictionary<string, string>> for TeamProject to accept them?
I have found the page for the property (https://learn.microsoft.com/en-us/dotnet/api/microsoft.teamfoundation.core.webapi.teamproject.capabilities?view=azure-devops-dotnet&source=docs#Microsoft_TeamFoundation_Core_WebApi_TeamProject_Capabilities), but I could not find an example of what microsoft expects for the property. Dictionary<string, Dictionary<string, string>> is vague and does not explain how the Version Control and Work Item Process is set for the dictionary. I would have expected something like this:
var capabilities = new Dictionary<string, string>();
capabilities.Add("Version Control", "Git");
capabilities.Add("Work Item Process", "Agile");
As you can see this does not meet the requirement of Dictionary<string, Dictionary<string, string>>, but rather Dictionary<string, string>. So what am I missing/requiring and am I doing it the correct way?
You may use this code to set up capabilities:
private Dictionary<string, Dictionary<string, string>> SetCapabilities(string processName, string versionControl)
{
Dictionary<string, string> processProperties = new Dictionary<string, string>();
processProperties.Add("Agile","adcc42ab-9882-485e-a3ed-7678f01f66bc");
processProperties.Add("CMMI","27450541-8e31-4150-9947-dc59f998fc01");
processProperties.Add("SCRUM","6b724908-ef14-45cf-84f8-768b5384da45");
Guid processId = Guid.Parse(processProperties[processName]);
Dictionary<string, string> processProperaties = new Dictionary<string, string>();
processProperaties[TeamProjectCapabilitiesConstants.ProcessTemplateCapabilityTemplateTypeIdAttributeName] =
processId.ToString();
Dictionary<string, string> versionControlProperties = new Dictionary<string, string>();
versionControlProperties[TeamProjectCapabilitiesConstants.VersionControlCapabilityAttributeName] = versionControl =="Tfvc"?
SourceControlTypes.Tfvc.ToString():
SourceControlTypes.Git.ToString();
Dictionary<string, Dictionary<string, string>> capabilities = new Dictionary<string, Dictionary<string, string>>();
capabilities[TeamProjectCapabilitiesConstants.VersionControlCapabilityName] =
versionControlProperties;
capabilities[TeamProjectCapabilitiesConstants.ProcessTemplateCapabilityName] =
processProperaties;
return capabilities;
}

How can I insert values into a multi-layer Dictionary in C#?

I have to write a Dictionary which will be
Dictionary<int, Dictionary<string, string>> dictionary = new Dictionary<int, Dictionary<string, string>>() { };
so later i'll just check and get values like
if (dictionary[index].key* == value) { stuff; } //*or maybe it's [index][key], that's not the matter
I just don't know and understand how to write the various elements inside the dictionary (i already searched here and online), the proper syntax, anything i try gets an error. Hope you can help, thank you in advance!
The name index isn't really appropriate, because dictionaries don't use indices they use keys.
However, to add a new sub-dictionary:
dictionary[i] = new Dictionary<string, string>();
To add / replace a value in an existing sub-dictionary:
dictionary[i][key] = value;
If you want to safely insert a new value when a sub-dictionary may or may not have been created, you could create an extension method:
public static void Insert(this Dictionary<int, Dictionary<string, string>> dict, int i, string key, string value)
{
if (!dict.ContainsKey(i)) dict[i] = new Dictionary<string, string>();
dict[i][key] = value;
}
Then use like this:
dictionary.Insert(1, "SomeKey", "SomeValue");
Just note that this will overwrite keys in the sub-dictionary if the same key is inserted more than once.
To insert into this object:
Dictionary<int, Dictionary<string, string>> dictionary = new Dictionary<int, Dictionary<string, string>>() { };
You'll need to do multiple inserts. So something like:
//create the first level and instanciate a new dictionary object
dictionary.Add(1234, new Dictionary<string, string>());
//insert into the dictionary created above
dictionary[1234].Add("test", "test");
dictionary[1234] here returns a Dictionary<string, string> where 1234 is the key added in dictionary.Add(1234, new Dictionary<string, string>());
How about using collection initialisers? This is great if you have constant values that you want the dictionary to contain:
var dictionary = new Dictionary<int, Dictionary<string, string>>() {
[111] = new Dictionary<string, string> {
["nested key1"] = "value 1",
["nested key2"] = "value 2",
["nested key3"] = "value 3",
["nested key4"] = "value 4",
},
[222] = new Dictionary<string, string> {
["nested key5"] = "value 5",
["nested key6"] = "value 6",
["nested key7"] = "value 7",
["nested key8"] = "value 8",
},
};
dictionary has type Dictionary<int, Dictionary<string, string>>, so var b = dictionary[3] has type Dictionary<string, string>, and to get an entry of b use syntax b["Hello"] to get a string.
If you want to write them in one clause, use (dictionary[3])["Hello"]. Since operator[] is left-associative, (dictionary[3])["Hello"] can be written as dictionary[3]["Hello"].

Need help manually adding to a dictionary

I am confused I am trying to manually add entries to a Dictionary but its throwing an error at the first comma. Any help is appreciated thank you.
private Dictionary<string, Dictionary<string, string>> packData =
new Dictionary<string, Dictionary<string, string>>()
{
{
"Test", //issue here
{
"Test" , "Test"
}
};
};
You'll want to be explicit about the inner dictionary:
new Dictionary<string, Dictionary<string, string>>()
{
{
"Test",
new Dictionary<string, string>
{
"Test" , "Test"
}
};
};
The rule to follow here is "imagine if the thing in the braces was replaced with a call to Add". In your original code, we would have lowered this to:
temp = new Dictionary<string, Dictionary<string, string>>();
temp.Add("Test", { "Test", "Test" });
Which is not legal code. But
temp = new Dictionary<string, Dictionary<string, string>>();
temp.Add("Test", new Dictionary<string, string>(){ "Test", "Test" });
is legal, and in turn corresponds to
temp = new Dictionary<string, Dictionary<string, string>>();
temp2 = new Dictionary<string, string>();
temp2.Add("Test", "Test");
temp.Add("Test", temp2);
I often find when I'm confused that it helps to "lower" the code into its more basic form to understand what's going on.
There are some situations in which the compiler is smarter about understanding the intended meaning of nested braces like in your original code, but unfortunately this is not one of them. See the specification for more details about what is and is not supported; you'll want to search for "object initializers" and "collection initializers".

C# :- Loop over 4 Dictionaries

I've 4 Dictionaries like,
Dictionary<string, string> home = new Dictionary<string, string>();
Dictionary<string, string> home1 = new Dictionary<string, string>();
Dictionary<string, string> away1 = new Dictionary<string, string>();
Dictionary<string, string> away2= new Dictionary<string, string>();
now I want to perform Assert for each of them on their Keys and values. How should i do that ?
i was thinking to adding them as below,
var dic = new[] { home , home1 , away1 , away2};
and then use Switch but it seems difficult as switch can't be used on array. So how should i approach this one ?
Why don't you create a function for asserting a dictionary, then loop over the array and call it, something like this:
foreach (var element in dic)
{
AssertOnDictioanry(element);
}
Hope this was useful.

Get dictionary key if value contains string

I have this Dictionary:
static Dictionary<int, string> Players = new Dictionary<int, string>();
dictionary.Add(1, "Chris [GC]");
dictionary.Add(2, "John");
dictionary.Add(3, "Paul");
dictionary.Add(4, "Daniel [GC]");
I want to get the key of values that contains "[GC]"
Any idea how?
Thanks.
Use LINQ:
var result = Players.Where(p => p.Value.Contains("[GC]")).Select(p => p.Key);
Use a query like below.
var itemsWithGC = dictionary.Where(d => d.Value.Contains("[GC]")).Select(d => d.Key).ToList();
foreach (var i in itemsWithGC)
{
Console.WriteLine(i);
}
Actually there's a more performant way of solving this issue, but it might require some refactor...
Whenever you add a new player containing "[GC]", you can fill a HashSet<int>:
Dictionary<int, string> Players = new Dictionary<int, string>();
HashSet<int> gcPlayers = new HashSet<int>();
dictionary.Add(1, "Chris [GC]");
gcPlayers.Add(1);
dictionary.Add(2, "John");
dictionary.Add(3, "Paul");
dictionary.Add(4, "Daniel [GC]");
gcPlayers.Add(4);
So now getting all keys which have "[GC]" is as easy as using the whole set called gcPlayers.
This will avoid a query and iterate the entire dictionary to get all coincidences, while you'll avoid adding duplicates to gcPlayers because it's a set (i.e. an unordered collection of unique values).

Categories