Adding to Values of a Dictionary - c#

With simpler dictionaries like this Dictionary<key,value> I know I can add an item to the dictionary like this:
if(!myDic.ContainKeys(key))
myDic[key] = value;
But how about a more complex dictionary like this:
Dictionary myDic<string, List<MyClass>>
where each key might have a list of values of my class? How do we add to that?

Here is a code snippet that I use for this:
// This is the list to which you would ultimately add your value
List<MyClass> theList;
// Check if the list is already there
if (!myDict.TryGetValue(key, out theList)) {
// No, the list is not there. Create a new list...
theList = new List<MyCLass>();
// ...and add it to the dictionary
myDict.Add(key, theList);
}
// theList is not null regardless of the path we take.
// Add the value to the list.
theList.Add(newValue);
This is the most "economical" approach, because it does not perform multiple searches on the dictionary.

The same way:
myDic[key] = new List<MyClass()>();
If the list is already there and you want to add to it:
myDic[key].Add(new MyClass());

You can use TryGetValue method:
List<MyClass> list;
if (myDic.TryGetValue(key, out list))
list.Add(value); // <- Add value into existing list
else
myDic.Add(key, new List<MyClass>() {value}); // <- Add new list with one value

If the value to add is an item for the list, you can do:
if(!myDic.Keys.Contains(key)) {
myDic[key] = new List<MyClass>();
}
myDic[key].Add(value);

Related

Remove all elements from a Key value pair which are equal to elements in a list?

I have two list
static List<dynamic> List1= new List<dynamic>();
list<string> List2
List1 is {Message='asdasd',Mobilenum=995955}
i want to remove all elements from List1 if the value in list2 is there in list1?
I have done this but it is not working
List1.RemoveAll(c => list2.ToList().Exists(n => n.Mobilenum== c.Values));
List1.RemoveAll(c => List2.Contains(c.Mobilenum));
But replace dynamic with the real type. Normally you don't need to use it. If it's an anonymous type and you have to pass this list around, consider to implement a new type with these properties.
First, create a type instead of using dynamic:
public class MyType
{
public string Message;
public string Mobilenum;
}
Then, you can do:
var List1 = new List<MyType>();
// ...build your list
var List2 = new List<string>();
// ...build your other list
var res = List1.Where(x => !List2.Contains(x.Mobilenum));
Avoid using Remove unless you're sure you want to throw away the information instead of just "filtering" it for a particular use.

What type is the best for loose numerically-indexed lists in C#?

What I need is something like an array but letting me to assign an element to whatever an index at any time and check if there is already a value assigned to particular index approximately like
MyArray<string> a = new MyArray<string>();
a[10] = "ten";
bool isTheFifthElementDefined = a[5] != null; // false
Perhaps Dictionary<int, string> with its ContainsKey method could do, but isn't there a more appropriate data structure if I want an ordered collection with numeric keys only?
I am also going to need to iterate through the defined elements (with foreach or linq preferably) accessing both the value and the key of current element.
As you mentioned Dictionary seems more appropriate for this.But you can do it with generic lists,for example, when you are creating your list you can specify an element count,and you can give a default temporary value for all your elements.
List<string> myList = new List<string>(Enumerable.Repeat("",5000));
myList[2300] = "bla bla bla..";
For int:
List<int> myList = new List<int>(Enumerable.Repeat(0,5000));
For custom type:
List<MyClass> myList = new List<MyClass>(Enumerable.Repeat(new MyClass(), 100));
Ofcourse It is not the best solution...
Note: Also you can use SortedList instead of Dictionary if you want an ordered collection by keys:
SortedList<TKey, TValue> : Represents a collection of key/value pairs that are sorted by key based on the associated IComparer implementation.
If you need key/value pairs you cannot use a list, you'll need a Dictionary.
The implementation is pretty snappy so don't be too afraid about performance (as long as you don't put too much values in it).
You can iterate over it with
foreach(KeyValuePair<int, string> kvp in dict)
{
}
If you need to order it you can use a list:
List<int> ordered = new List(dict.Keys);
ordered.Sort();
foreach(int key in ordered)
{
}

A List of List and Object

I want a List of OtherObjects all belonging to certain Objects.
Is it possible to create a List like so?
List<Object, List<OtherObject>>
Or should I create a new class and do?
List<NewClass>
Or should I do something else overall? The size is dynamic so I didn't want to use an array.
How can I achieve this?
You want a Dictionary<>, e.g.
Dictionary<Object, List<OtherObject>>
Where Object is the Key and List<OtherObject> is the Value
You can use Tuple<Object, List<OtherObject>> to achieve what you want.
Tuples is for composition of properties when you don't want to create special class. You can use Tuple<Object, AnotherObject, AnotherAnotherObject> if you need.
Your code will be something like:
List<Tuple<Object, List<OtherObject>>> list;
and work with it:
foreach(var tuple in list)
{
var object = tuple.Item1;
var innerList = tuple.Item2;
}
try Using
Dictionary<Object, List<OtherObject>>
Hope i helped

How to retrieve first row from dictionary in C#?

How to retrieve first row from this dictionary. I put around some 15 records.
Dictionary<string, Tuple<string, string>> headINFO =
new Dictionary<string, Tuple<string, string>> { };
You can use headINFO.First(), but unless you know that there always will be at least one entry in headINFO I would recommend that you use headINFO.FirstOrDefault().
More information on the differences between the two available here.
Edit: Added simple examples
Here is a quick example on how to use FirstOrDefault()
var info = headINFO.FirstOrDefault().Value;
Console.WriteLine(info.Item1); // Prints Tuple item1
Console.WriteLine(info.Item2); // Prints Tuple item2
If you want to print multiple items you can use Take(x). In this case we will loop through three dictionary items, but you can easily modify the number to grab more items.
foreach (var info in headINFO.Take(3))
{
Console.WriteLine(info.Value.Item1);
Console.WriteLine(info.Value.Item2);
}
You should also keep in mind that the above foreach does not allow you to modify the values of your Dictionary entries directly.
Edit2: Clarified usage of First() and added clean foreach example
Keep in mind that while First() and FirstOrDefault() will provide you with a single item it does in no way guarantee that it will be the first item added.
Also, if you simply want to loop through all the items you can remove the Take(3) in the foreach loop mentioned above.
foreach (var info in headINFO)
{
Console.WriteLine(info.Key); // Print Dictionary Key
Console.WriteLine(info.Value.Item1); // Prints Turple Value 1
Console.WriteLine(info.Value.Item2); // Prints Turple Value 2
}
Dictionaries are unordered, so there is no way to retrieve the first key-value pair you inserted.
You can retrieve an item by calling the LINQ .First() method.
The easiest way is just to use Linq's First extension method:
var firstHead = headINFO.First();
Or if you want to be safer, the FirstOrDefault method will return null if the dictionary is empty:
var firstHead = headINFO.FirstOrDefault();
If you'd like to loop through all items in the dictionary, try this:
foreach(var head in headINFO)
{
...
}
Try this code.
headINFO.FirstOrDefault();
Try this:
int c=0;
foreach(var item in myDictionary)
{
c++;
if(c==1)
{
myFirstVar = item.Value;
}
else if(c==2)
{
mySecondVar = item.Value;
}
......
}

Loop in Dictionary

I use this:
foreach(KeyValuePair<String,String> entry in MyDic)
{
// do something with entry.Value or entry.Key
}
The problem is that I can't change the value of entry.Value or entry.Key
My question is that how can i change the value or key when looping through a dictionary?
And, does dictionary allow duplicated key? And if yes, how can we avoid ?
Thank you
You cannot change the value of a dictionary entry while looping through the items in the dictionary, although you can modify a property on the value if it's an instance of a reference type.
For example,
public class MyClass
{
public int SomeNumber { get; set;}
}
foreach(KeyValuePair<string, MyClass> entry in myDict)
{
entry.Value.SomeNumber = 3; // is okay
myDict[entry.Key] = new MyClass(); // is not okay
}
Trying to modify a dictionary (or any collection) while looping through its elements will result in an InvalidOperationException saying the collection was modified.
To answer your specific questions,
My question is that how can i change the value or key when looping through a dictionary?
The approach to both will be pretty much the same. You can either loop over a copy of the dictionary as Anthony Pengram said in his answer, or you can loop once through all the items to figure out which ones you need to modify and then loop again through a list of those items:
List<string> keysToChange = new List<string>();
foreach(KeyValuePair<string, string> entry in myDict)
{
if(...) // some check to see if it's an item you want to act on
{
keysToChange.Add(entry.Key);
}
}
foreach(string key in keysToChange)
{
myDict[key] = "new value";
// or "rename" a key
myDict["new key"] = myDict[key];
myDict.Remove(key);
}
And, does dictionary allow duplicated key? And if yes, how can we avoid ?
A dictionary does not allow duplicate keys. If you want a collection of <string, string> pairs that does, check out NameValueCollection.
Updating the dictionary in the loop is going to be a problem, as you cannot modify the dictionary as it is being enumerated. However, you can work around this pretty easily by converting the dictionary to a list of KeyValuePair<> objects. You enumerate that list, and then you can modify the dictionary.
foreach (var pair in dictionary.ToList())
{
// to update the value
dictionary[pair.Key] = "Some New Value";
// or to change the key => remove it and add something new
dictionary.Remove(pair.Key);
dictionary.Add("Some New Key", pair.Value);
}
For the second part, the key in a dictionary must be unique.
KeyValuePair's Key and value are read only. But you can change a value like that:
dictionary[key].Value = newValue;
But if you want to change the key, you will have to remove/add a key.
And no, a Dictionary does not allow duplicate keys, it will throw an ArgumentException.
You cannot modify keys while enumerating them.
One method I use for changes to the collection while enumerating them is that I do break; out of the foreach loop when a match is found and item is modified, and am restarting the whole enumeration all over again. That's one way of handling it...
No, Dictionary can't have duplicate keys. If you want something that will sort by key and allow duplicates, you should use some other data structure.
You can do this like
for (int i = 0; i < MyDic.Count; i++)
{
KeyValuePair<string, string> s = MyDic.ElementAt(i);
MyDic.Remove(s.Key);
MyDic.Add(s.Key, "NewValue");
}
And Dictionary doesn't allow duplicates

Categories