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;
}
......
}
Related
I'm currently working on a project where I have to loop over a dictionary. I only want to loop over the keys in this dictionary which contain a substring of a. So for a dictionary (key, value) I only want to loop through the pairs in this dictionary for which the key contains A.
How would I do this?
How would I do this?
Dictionaries only offer O(1) (fast) access when checking for equality. There's not a way to "select" keys that contain a value without looping:
foreach(var entry in myDictionary)
{
if(entry.Key.Contains("A"))
// do something with entry.Value
}
You could use the Where method from Linq but it doesn't offer any performance improvement (it still loops internally):
foreach(var entry in myDictionary.Where(e => e.Key.Contains("A"))
{
// do something with entry.Value
}
Lots of ways. Here is one example (not tested).
var keys = dictionary.Keys.Where(k => k.Contains(a));
foreach (var matchingKey in keys)
{
var value = dictionary[matchingKey];
// Do something
}
i know my question isn't really detailled, by i didn't know how to ask it, since i don't really how to explain my issue without writting many lines. Anyway, here is my actual code
var numberOfItemInTempDict = 0;
Dictionary<int, Dictionary<string, List<dynamic>>> tempDict = new Dictionary<int, Dictionary<string, List<dynamic>>>();
foreach (KeyValuePair<int, Dictionary<string, List<dynamic>>> kvp in alertSortedByCompanyAndType.ToList())
{
// We iterate through all the companies id
foreach (var kvp2 in kvp.Value)
{
// We iterate through all array of type in one company
foreach (var item in kvp2.Value)
{
// We iterate through all the data for one array of type in one company
if (!tempDict.ContainsKey(kvp.Key))
{
tempDict.Add(kvp.Key, new Dictionary<string, List<dynamic>>());
}
if (!tempDict[kvp.Key].ContainsKey(kvp2.Key))
{
tempDict[kvp.Key].Add(kvp2.Key, new List<dynamic>());
}
// We add the item to the tempDictionary
tempDict[kvp.Key][kvp2.Key].Add(item);
// And after adding it, we delete it from the original dictionary
alertSortedByCompanyAndType[kvp.Key][kvp2.Key].Remove(item);
numberOfItemInTempDict++;
if (numberOfItemInTempDict >= 250)
{
break;
}
}
if (numberOfItemInTempDict >= 250)
{
break;
}
}
if (numberOfItemInTempDict >= 250)
{
break;
}
}
The problem here seems to be that i'm deleting items from alertSortedByCompanyAndType dictionary, but i'm iterating to it as well, so there is a InvalidOperationException since the collection was modified during iteration.
But, i also saw somewhere that by doing a ToList(), it's recreating alertSortedByCompanyAndType, and then, you can do whatever you want with the original dict since the ToList() will be our iterated dictionary. I could have missinterpreted it as well, and that's probably the case.
(If you have any improvements for my code, feel free to tell me or explain what i do wrong, i'm quite new, the following text is mandatory for the question answer)
For the few if at the end of each foreach, it's because i want it to iterate only 250 times, but there could be like 250 items for one company, or either 1 item for 250 company, or whatever, maybe i could just do a function to then just return instead of doing ugly if statement like i do.
For the tempDict that i used above, it's because both dictionary can be populated asynchronously, and the first dictionary could contain like 2000 items, but i want the tempDict to only have 250 of them, so i can pass the tempDict to another function that is after that.
And for the dynamic keyword for the list, it contains items that can be from 9 different classes (for now at least) that i receive in json from another program, so i deserialize them, using dynamic keyword since i don't really need to access to all the data in it, only part of it, i use the class to then register alerts to Amazon SQS.
You can try to split the copying and deleting. Put the items you want to remove in a list instead of removing them right away. After you are done remove them afterwards from the actual dictionary.
Something like this (pseudocode, untestet)
List<ValueTuple<string, string, object>> toBeDeleted = new List...; //asuming kvp.Key and kvp2.Key are strings and the item is object, use your actuall types
....
//instead of alertSortedByCompanyAndType[kvp.Key][kvp2.Key].Remove(item);
toBeDeleted.Add((kvp.Key,kvp2.Key,item))
....
//after the foreach nests
foreach( var d in toBeDeleted)
alertSortedByCompanyAndType[d.Item1][d.Item2].Remove(d.Item3);
This question already has answers here:
How to iterate over a dictionary?
(29 answers)
Closed 8 years ago.
I have a:
var selectedDates = new Dictionary<string, string>();
selectedDates.Add("2014-06-21", DateTime.Now.ToLongDateString());
selectedDates.Add("2014-07-21", DateTime.Now.AddDays(5).ToLongDateString());
selectedDates.Add("2014-08-21", DateTime.Now.AddDays(9).ToLongDateString());
selectedDates.Add("2014-09-21", DateTime.Now.AddDays(14).ToLongDateString());
How can I loop trough items without knowing the key?
For example I want to get the value of the item[0]
If I do:
var item = selectedDates[0].value; // I get an error
How can I loop trough items without knowing the key?
For example I want to get the value of the item[0]
You want to treat the dictionary as (ordered) collection similar to a list or array and get the first item in it?
You can because a Dictionary<string, string> is an IEnumerable<KeyValuePair<string, string>> implicitly. Just use First or FirstOrDefault:
string valueAtFirstPosition = selectedDates.First().Value;
However, note that a dictionary is not meant to be used as as an ordered collection. It is a collection which can be used to fast-lookup a value by a key. But you can enumerate it anyway.
foreach(KeyValuePair<string, string>keyVal in selectedDates)
{
Console.WriteLine("Key: {0} Value: {1}", keyVal.Key, keyVal.Value);
}
You should simply not rely on that order. I think in the current implementation the order is stable as long as you don't delete items. Read
Read: Why is a Dictionary “not ordered”?
try this
foreach (string key in selectedDates.Keys)
{
var item = selectedDates[key];
}
It's simple, loop trough it with a foreach or to get a specific index do:
var date = selectedDates.ElementAt(0).Value;
Let me put together two things for you. Firstly, you can loop or use LINQ to access elements, just as you could do it in a list as well:
var dict = new Dictionary<string, string>();
// loop
foreach (var item in dict)
{
var key = item.Key;
var value = item.Value;
}
// "first" (see below)
var firstItem = dict.First();
However, be aware that what you're referring to as the first item can be pretty much any item in the Dictionary. Dictionaries store elements in any order that is convenient for a lookup (so do sets).
This order is known for some implementations, but lists or arrays might fit better when the order of the elements is important. A Dictionary in .NET is an implementation of a hash table data structure (tree map is another map implementation).
try this :
foreach(var key in selectedDates.Keys)
{
var value = selectedDates[key];
}
Use this overload of Where:
var result = selectedDates.Where((d,i)=>i==0);
Try:
foreach (var date in selectedDates)
{
var item = date.Value;
}
I have one Dictionary and added some elements on it.for example,
Dictionary<string, string> d = new Dictionary<string, string>();
d.Add("Content","Level0");
d.Add("gdlh","Level1");
d.Add("shows","Level2");
d.Add("ytye","Level0");
In C#, Dictionary keeps elements in natural order.But i now want to iterate those values from last to first(ie, Reverse order).i mean,
first i want to read ytye then shows,gdlh and finally Content.
Please guide me to get out of this issue...
Just use the Linq extension method Reverse
e.g.
foreach( var item in d.Reverse())
{
...
}
Use LINQ Reverse, but note that does not reverse in place:
var reversed = d.Reverse();
But note that this is not a SortedDictionary, so the order is not necessarily guaranteed in the first place. Perhaps you want OrderByDescending instead?
Maybe OrderByDescending on the key. Like this:
d.OrderByDescending (x =>x.Key)
Foreach like this:
foreach (var element in d.OrderByDescending (x =>x.Key))
{
}
It's available with Linq: d.Reverse()
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