I have created:
Dictionary<string, List <KeyValuePair<string,string>>> diction = new Dictionary<string, List<KeyValuePair<string,string>>>();
Later I've added to that list:
diction.Add(firststring, new List<KeyValuePair<string,string>>());
diction[firststring].Add(new KeyValuePair<string, string>(1ststringlist, 2ndstringlist));
So now, If I want to read and show on screen this dictionary, how would I do it with foreach loop ? It's like 3 dimmension syntax, don't now how to create it and access it.
Also can anyone explain how to read this part?
diction[firststring].Add
What this marks [] excatly mean? I read whole dictionary there?
thank You for answer and Your time.
Dictionaries store key / value pairs. In your case, your key type is string and value type is List <KeyValuePair<string,string>>.So when you do:
diction[firststring]
firststring is your Key and you are trying to access a List <KeyValuePair<string,string>>.Your best option is nested loops I think.if you want to display all values. For example:
foreach(var key in dict.Keys)
{
// dict[key] returns List <KeyValuePair<string,string>>
foreach(var value in dict[key])
{
// here type of value is KeyValuePair<string,string>
var currentValue = value.Value;
var currentKey = value.Key;
}
}
For printing the datastructure, try this:
// string.Join(separator, enumerable) concatenates the enumerable together with
// the separator string
var result = string.Join(
Environment.NewLine,
// on each line, we'll render key: {list}, using string.Join again to create a nice
// string for the list value
diction.Select(kvp => kvp.Key + ": " + string.Join(", ", kvp.Value)
);
Console.WriteLine(result);
In general, to loop over the values of a dictionary, you can use foreach or LINQ just like with any IEnumerable data structure. IDictionary is an IEnumerable>, so the foreach variable will be of type KeyValuePair.
The syntax diction[key] allows you to get or set the value of the dictionary stored at the index key. It's similar to how array[i] lets you get or set the array value at index i. For example:
var dict = new Dictionary<string, int>();
dict["a"] = 2;
Console.WriteLine(dict["a"]); // prints 2
If all you need to do is store rows of 3 string values each, then the data structure you are using is far too complicated.
Here's a much simpler example, based on the Tuple class:
public class Triplet : Tuple<string, string, string>
{
public Triplet(string item1, string item2, string item3) : base(item1, item2, item3)
{
}
}
So you just define a class Triplet that holds 3 strings, like above. Then you simply create a List of Triplets in your code:
// Your code here
var data = new List<Triplet>();
// Add rows
data.Add(new Triplet("John", "Paul", "George"));
data.Add(new Triplet("Gene", "Paul", "Ace"));
// Display
foreach(Triplet row in data)
{
Console.WriteLine("{0}, {1}, {2}", row.Item1, row.Item2, row.Item3);
}
and this is far simpler to read, understand, and maintain.
Related
I’m a rookie in programming and I have a problem understanding how to print elements from a List.
In the task I’ve been given, I receive:
List<Dictionary<string,string>>() list = new
List<Dictionary<string,string>>();
list.Add(processString(string, string));
list.Add(processString(string, string));
The processStrig is a Dictionary<string,string> and the keys are the same for both records.
I tried to create a new Dictionary and then populate it with foreach:
Dictionary<string,string>() dict = new Dictionary<string, string>();
foreach (Dictionary<string,string>r in list)
{
foreach (string inner in r.Keys)
{
if (!dict.ContainsKey(inner))
{
dict.Add(inner, r[inner]);
}
}
}
and then print the new dict with another foreach, but it shows me only the first input because the keys are the same. So basically my question is how to print the both inputs? The output should look like this:
The output should look like this:
[0]
"count":"some string"
"order":"some string"
[1]
"count":"some other string"
"order":"some other string"
If you are looking for a loop solution, you can try something like this:
List<Dictionary<string, string>> list = ...
for (int i = 0; i < list.Count; ++i) {
Console.WriteLine($"[{i}]");
if (list[i] == null)
Console.WriteLine("[null]");
else
foreach (var pair in list[i])
Console.WriteLine($"\"{pair.Key}\" : \"{pair.Value}\"");
}
Let's have a method that makes you a dictionary:
public static Dictionary<string, string> MakeMeADictionary(string value1, string value2){
var d = new Dictionary<string, string>();
d["key1"] = value1;
d["key2"] = value2;
return d;
}
Let's call it twice, adding the results to a List:
var listOfDicts = new List<Dictionary<string, string>>();
listOfDicts.Add(MakeMeADictionary("first val", "second val"));
listOfDicts.Add(MakeMeADictionary("third val", "fourth val"));
Let's enumerate the list, and then each dictionary inside it:
foreach(var dict in listOfDicts){
Console.WriteLine("Enumerating a dictionary");
foreach(var keyValuePair in dict)
Console.WriteLine($"Key is: {keyValuePair.Key}, Value is: {keyValuePair.Value}");
}
Result:
Enumerating a dictionary
Key is: key1, Value is: first val
Key is: key2, Value is: second val
Enumerating a dictionary
Key is: key1, Value is: third val
Key is: key2, Value is: fourth val
Strive for variable names that make your code make sense; plurals or names of colelction types for collections, foreach vars that singularly make sense for the plural being enumerated etc.. If this were a less contrived example, and e.g. it were a List<Person> I'd call it people, perhaps, and have foreach(var person in people).. I couldn't understand your choice of r in foreach(var r in list)
This question already has answers here:
Remove Item in Dictionary based on Value
(6 answers)
Closed 9 years ago.
The question should be clear from the title itself. I need to check if an item exist in the dictionary and remove it from the dictionary in C#. The only catch is that i have to do this using only the value item and not the key.
The declaration is as below:
IDictionary<string, myCustomClassObject> clients = new IDictionary<string, myCustomClassObject>();
Now i fill in the dictionary by:
clients["key"] = myCustomClassObject1;
Now how can i find and remove this item myCustomClassObject1 from my Dictionary. I only want to use the value item and not the key
Is this doabale...if so please guide...
regards
Edit: Thank you all....got valuable comments...probably have some thinking to do ...thanks
It depends on how you need it to perform. If you can accept O(N) performance, you could just do something like:
foreach(var pair in clients) {
if(pair.Value == expected) {
clients.Remove(pair.Key);
break;
}
}
However, if you need faster you would need two dictionaries - one the reverse of the other (i.e. keyed by the instances). So when adding, you would do:
clientsByKey.Add(key, value);
clientsByValue.Add(value, key);
so you can do (to remove-by-value):
string key;
if(clientsByValue.TryGetValue(value, out key)) {
clientsByValue.Remove(value);
clientsByKey.Remove(key);
}
or similarly (to remove-by-key):
Foo value;
if(clientsByKey.TryGetValue(key, out value)) {
clientsByValue.Remove(value);
clientsByKey.Remove(key);
}
It's not very efficient to search a dictionary by it's values. However, you can use Linq to find all entries with a given value.
IEnumerable<KeyValuePair<string, myCustomClassObject>> pairs = clients
.Where(entry => entry.Value.Equals(myCustomClassObject1)).ToList();
foreach (KeyValuePair<string, myCustomClassObject> kv in pairs)
clients.Remove(kv.Key);
This should do it. It removes all clients having a given value.
while (clients.ContainsValue(myCustomClassObject1))
clients.Remove(clients.Where(x => x.Value == myCustomClassObject1).FirstOrDefault().Key);
Or create a new dictionary without the values you want removed
clients = clients.Where(x => x.Value != myCustomClassObject1).ToDictionary(k => k.Key, v => v.Value);
If the collection only contains one item with the value to be removed then you can use one of the other answers here, which will work just fine.
However, if your collection can have multiple items with the same value then you need to be careful.
You cannot modify a collection while iterating over it, so you will need to find the keys of all the items that you want to remove in one loop and put them in a list, and then iterate over that list in a separate loop to delete the items.
For example:
using System;
using System.Collections.Generic;
using System.Linq;
namespace Demo
{
class Program
{
void run()
{
var dict = new Dictionary<string, int>
{
{"Key1", 1},
{"Key2", 2},
{"Key3", 3},
{"Key4", 2},
{"Key5", 4}
};
int valueToRemove = 2;
var keysToRemove = (from element in dict
where element.Value == valueToRemove
select element.Key).ToList();
foreach (var key in keysToRemove)
dict.Remove(key);
foreach (var element in dict)
Console.WriteLine("Key = {0}, Value = {1}", element.Key, element.Value);
}
static void Main(string[] args)
{
new Program().run();
}
}
}
Use,
Following will remove only first matching value
client newClient = new client();
foreach(KeyValuePair<string, client> client in clients) {
if(client.value.equals(newClient)) {
clients.remove(client.key);
break;
}
}
Or if you want to remove all matching values,
foreach(var client in clients.Where(kvp => kvp.Value == newClient).ToList()) {
clients.Remove(client.Key);
}
How can i select the value from the List of keyvaluepair based on checking the key value
List<KeyValuePair<int, List<Properties>> myList = new List<KeyValuePair<int, List<Properties>>();
Here I want to get the
list myList[2].Value when myLisy[2].Key=5.
How can i achieve this?
If you need to use the List anyway I'd use LINQ for this query:
var matches = from val in myList where val.Key == 5 select val.Value;
foreach (var match in matches)
{
foreach (Property prop in match)
{
// do stuff
}
}
You may want to check the match for null.
If you're stuck with the List, you can use
myList.First(kvp => kvp.Key == 5).Value
Or if you want to use a dictionary (which might suit your needs better than the list as stated in the other answers) you can convert your list to a dictionary easily:
var dictionary = myList.ToDictionary(kvp => kvp.Key);
var value = dictionary[5].Value;
Use Dictionary<int, List<Properties>>. Then you can do
List<Properties> list = dict[5];
As in:
Dictionary<int, List<Properties>> dict = new Dictionary<int, List<Properties>>();
dict[0] = ...;
dict[1] = ...;
dict[5] = ...;
List<Properties> item5 = dict[5]; // This works if dict contains a key 5.
List<Properties> item6 = null;
// You might want to check whether the key is actually in the dictionary. Otherwise
// you might get an exception
if (dict.ContainsKey(6))
item6 = dict[6];
NOTE
The generic Dictionary class, introduced in .NET 2.0, uses KeyValuePair.
ITs better you make use of
Dictionary<TKey, TValue>.ICollection<KeyValuePair<TKey, TValue>>
and use ContainsKey Method to check the the key is there or not ..
Example :
ICollection<KeyValuePair<String, String>> openWith =
new Dictionary<String, String>();
openWith.Add(new KeyValuePair<String,String>("txt", "notepad.exe"));
openWith.Add(new KeyValuePair<String,String>("bmp", "paint.exe"));
openWith.Add(new KeyValuePair<String,String>("dib", "paint.exe"));
openWith.Add(new KeyValuePair<String,String>("rtf", "wordpad.exe"));
if (!openWith.ContainsKey("txt"))
{
Console.WriteLine("Contains Given key");
}
EDIT
To get value
string value = "";
if (openWith.TryGetValue("tif", out value))
{
Console.WriteLine("For key = \"tif\", value = {0}.", value);
//in you case
//var list= dict.Values.ToList<Property>();
}
in your caseu it will be
var list= dict.Values.ToList<Property>();
First of all, apologies for the nasty title. I will correct it later.
I have some data like below,
"BOULEVARD","BOUL","BOULV", "BLVD"
I need a data structure that is O(1) for looking up any of this words by other. For example, if I use a dictionary I would need to store this keys/values like this, which looks odd to me,
abbr.Add("BLVD", new List<string> { "BOULEVARD","BOUL","BOULV", "BLVD" });
abbr.Add("BOUL", new List<string> { "BOULEVARD", "BOUL", "BOULV", "BLVD" });
abbr.Add("BOULV", new List<string> { "BOULEVARD", "BOUL", "BOULV", "BLVD" });
abbr.Add("BOULEVARD", new List<string> { "BOULEVARD", "BOUL", "BOULV", "BLVD" });
Which data structure to use to keep this data appropriate to my querying terms?
Thanks in advance
Create two HashMap - one maps word to a group number. And the other one maps group number to a list of words. This way you save some memory.
Map<String, Integer> - Word to Group Number
Map<Integer, List<String>> - Group Number to a list of words
You need two O(1) lookups - first to get the group number and then by it - get the list of words.
Assuming abbr is a Dictionary<String, IEnumerable<String>>, you could use the following function:
public static void IndexAbbreviations(IEnumerable<String> abbreviations) {
for (var a in abbreviations)
abbr.Add(a, abbreviations);
}
This will populate the dictionary with the provided list of abbreviations such that when any of them is looked up in the dictionary. It is slightly better than the example code you provided, because I am not creating a new object for each value.
From the documentation, "Retrieving a value by using its key is very fast, close to O(1), because the Dictionary(Of TKey, TValue) class is implemented as a hash table."
The choice of dictionary looks fine to me. As mentioned above, you should use the same list to be referenced in the dictionary. The code could go something like this:
var allAbrList = new List<List<string>>
{
new List<string> {"BOULEVARD", "BOUL", "BOULV", "BLVD"},
new List<string> {"STREET", "ST", "STR"},
// ...
};
var allAbrLookup = new Dictionary<string, List<string>>();
foreach (List<string> list in allAbrList)
{
foreach (string abbr in list)
{
allAbrLookup.Add(abbr, list);
}
}
The last part could be converted into LINQ to have less code, but this way it is easier to understand.
If you don't create a new list for each key, then a Dictionary<string, List<string>> will be fast and reasonably memory-efficient as long as the amount of data isn't enormous. You might also be able to get a little extra benefit from reusing the strings themselves, though the optimizer might take care of that for you anyway.
var abbr = new Dictionary<string, List<string>>;
var values = new List<string> { "BOULEVARD","BOUL","BOULV", "BLVD" };
foreach(var aValue in values) abbr.add(value, values);
As Petar Minchev already said, you can split your list into an list of groups and a list of keys that points to this group. To simplify this (in usage) you can write an own implementation of IDictionary and use the Add method to build those groups. I gave it a try and it seems to work. Here are the important parts of the implementation:
public class GroupedDictionary<T> : IDictionary<T,IList<T>>
{
private Dictionary<T, int> _keys;
private Dictionary<int, IList<T>> _valueGroups;
public GroupedDictionary()
{
_keys = new Dictionary<T, int>();
_valueGroups = new Dictionary<int, IList<T>>();
}
public void Add(KeyValuePair<T, IList<T>> item)
{
Add(item.Key, item.Value);
}
public void Add(T key, IList<T> value)
{
// look if some of the values already exist
int existingGroupKey = -1;
foreach (T v in value)
{
if (_keys.Keys.Contains(v))
{
existingGroupKey = _keys[v];
break;
}
}
if (existingGroupKey == -1)
{
// new group
int newGroupKey = _valueGroups.Count;
_valueGroups.Add(newGroupKey, new List<T>(value));
_valueGroups[newGroupKey].Add(key);
foreach (T v in value)
{
_keys.Add(v, newGroupKey);
}
_keys.Add(key, newGroupKey);
}
else
{
// existing group
_valueGroups[existingGroupKey].Add(key);
// add items that are new
foreach (T v in value)
{
if(!_valueGroups[existingGroupKey].Contains(v))
{
_valueGroups[existingGroupKey].Add(v);
}
}
// add new keys
_keys.Add(key, existingGroupKey);
foreach (T v in value)
{
if (!_keys.Keys.Contains(v))
{
_keys.Add(v, existingGroupKey);
}
}
}
}
public IList<T> this[T key]
{
get { return _valueGroups[_keys[key]]; }
set { throw new NotImplementedException(); }
}
}
The usage could look like this:
var groupedDictionary = new GroupedDictionary<string>();
groupedDictionary.Add("BLVD", new List<string> {"BOUL", "BOULV"}); // after that three keys exist and one list of three items
groupedDictionary.Add("BOULEVARD", new List<string> {"BLVD"}); // now there is a fourth key and the key is added to the existing list instance
var items = groupedDictionary["BOULV"]; // will give you the list with four items
Sure it is a lot of work to implement the whole interface but it will give to an encapsulated class that you don't have to worry about, after it is finished.
I don't see a reason to define the value part of your dictionary as a List<string> object, but perhaps that is your requirement. This answer assumes that you just want to know whether the word essentially means "Boulevard".
I would pick one value as the "official" value and map all of the other values to it, like this:
var abbr = new Dictionary<string, string>(StringComparer.CurrentCultureIgnoreCase);
abbr.Add("BLVD", "BLVD"); // this line may be optional
abbr.Add("BOUL", "BLVD");
abbr.Add("BOULV", "BLVD");
abbr.Add("BOULEVARD", "BLVD");
Alternatively, you could define an enum for the value part of the dictionary, as shown below:
enum AddressLine1Suffix
{
Road,
Street,
Avenue,
Boulevard,
}
var abbr = new Dictionary<string, AddressLine1Suffix>(StringComparer.CurrentCultureIgnoreCase);
abbr.Add("BLVD", AddressLine1Suffix.Boulevard);
abbr.Add("BOUL", AddressLine1Suffix.Boulevard);
abbr.Add("BOULV", AddressLine1Suffix.Boulevard);
abbr.Add("BOULEVARD", AddressLine1Suffix.Boulevard);
I have declared a dictionary like this:
Dictionary<string, KeyValuePair<string, string>> dc = new Dictionary<string, KeyValuePair<string, string>>();
now how can I loop through it? I wanted something like the following so I created that dictionary:
name1
oldValue1
newValue1
name2
oldValue2
newValue2
...
You can loop through it like so
foreach (var pair in dc)
{
string name = pair.Key;
string oldValue = pair.Value.Key;
string newValue = pair.Value.Value;
// use the values
}
But I have a feeling you're using the wrong tool for the job. It sounds to me like you really need to go ahead and define a proper class to hold the names and values, and then just work with a List<T> of that class.
foreach( KeyValuePair<string, string> kvp in dc )
{
Console.WriteLine("Key = {0}, Value = {1}", kvp.Key, kvp.Value);
}
When you loop a dictionary you use KeyValuePair that is generic. Since your dictionary contain the key as string and the value as string, this one will take also a string for both.
You can access the key with kvp.Key and the value with kvp.Value.
For your example, you are using a Dictionary of string that contain a value of KeyValuePair.
So, you can have the exact print you want with :
foreach( KeyValuePair<string, KeyValuePair<string,string>> kvp in dc )
{
Console.WriteLine(kvp.Key + " " + kvp.Value.Key + " "+ kvp.Value.Value);
}