C# Dictionary print list values by position - c#

From this example: https://stackoverflow.com/a/27034916/1312879
I have this kind of dictionary
Dictionary<int, List<string>> fileList = new Dictionary<int, List<string>>();
The example prints "fijo", "Frigy", "lijo", "liji", "vimal", "vilma"
How can I print "fijo", "lijo", "vimal", "Frigy", "liji", "vilma", I mean all the [0] position of each list, the [1] position and so on

You can code pretty much as you said:
foreach (var kvp in fileList)
{
Console.WriteLine (kvp.Value[0]);
}
foreach (var kvp in fileList)
{
Console.WriteLine (kvp.Value[1]);
}
And if there is more item in the inner list, you might want to use a loop for that, assuming they all have the same length:
for (int i = 0; i < fileList.First().Value.Count; i++)
{
foreach (var kvp in fileList)
{
Console.WriteLine (kvp.Value[i]);
}
}

Here you go:
for(int i=0; i < fileList.Values.Max(v=> v==null ? 0 : v.Length); i++)
{
foreach(var keyValuePair in fileList)
{
if(kvp.Value == null || i >= kvp.Value.Length)
continue;
Console.WriteLine(kvp.Value[i]);
}
}
However, I wonder reason behind traversing data structure in columnar fashion when it was created based on rows (or vice versa). You may be better off using different data structure that can serve all use cases.

Related

Prevent collection modified exception in a foreach loop in c#

I'm iterating over a dictionary Dictionary<double, int> diametersAndQuantities and the dictionary is modified. Obviously I'm getting an exception that the collection has been modified. How can I prevent this from happening?
foreach (var diametersAndQuantity in diametersAndQuantities)
{
// some operations here
// update
diametersAndQuantities[db] = n;
}
You can create a temporary list of the KeyValuePairs to iterate over and still update the dictionary.
foreach (var diametersAndQuantity in diametersAndQuantities.ToList())
{
// some operations here
// update
diametersAndQuantities[diametersAndQuantity.Key] = n;
}
you can use the ToList() to get the enumeration to be evaluated
similar to accepted answer - maybe a little faster
should use less memory
Dictionary<int, int> dic = new Dictionary<int, int>() { { 1, 2 }, { 2, 3 }, { 3, 2 } };
foreach (int value in dic.Values)
Debug.WriteLine(value);
foreach (int key in dic.Keys.ToList())
dic[key] = 12;
foreach (int value in dic.Values)
Debug.WriteLine(value);
Debug.WriteLine("done");

Using sortedList to count words in a List

For my homework, I have to use a SortedList to count words in a List with SortedList taking each entry and sorting it in alphabetical order before inserting. When it comes to display the data to the user, the data displayed should be displayed with sorting according to value instead of key.
Below is my attempt at this but I am getting 3 errors and I don't know how to resolve it. I am not allowed to use LINQ for this.
List<string> words = new List<string>(); <--- Already populated
This is my code of this implementation and I get 3 errors:
SortedList<string, int> d = new SortedList<string, int>();
bool InsideOfList = false;
foreach (string word in words)
{
InsideOfList = false;
foreach (KeyValuePair<string, int> keyvalPair in d)
{
if (keyvalPair.Key == word)
{
keyvalPair.Value += 1;
InsideOfList = true;
}
}
if (InsideOfList == false)
{
d.Add(word,1);
}
}
//Now instead of sorting by key I want to sort by value instead
SortedList<int, string> tempSortList = new SortedList<int, string>();
foreach (KeyValuePair<string, int> keyvalPair in d)
{
//trying to swap the value of previous SortedList with the Key of the new SortedList
tempSortList.Add(keyvalPair.Value, keyvalPair.Key);
}
for (int i = 0; i < 20; i++)
{
Console.WriteLine("\t{0}:\t{1}", tempSortList.GetKey(i), tempSortList.GetByIndex(i));
}
Here are my errors:
Property or indexer 'System.Collections.Generic.KeyValuePair<string,int>.Value' cannot be assigned to -- it is read only
'System.Collections.Generic.SortedList<int,string>' does not contain a definition for 'GetKey'
'System.Collections.Generic.SortedList<int,string>' does not contain a definition for 'GetByIndex'
You are confusing two things here. One is SortedList() and other is SortedList().
GetKey and GetKeyList are not present in SortedList(). You can use this instead of GetKey
tempSortList.ElementAt(index); // This will return you a KeyValuePair.
And for the first error you cannot assign value keyvalPair.Value has only getter. So you cannot set its value by doing += 1.
This is not quite good. Needs some improvement but it will work.
for (int i = 0; i < d.Count; i++)
{
if (d.ElementAt(i).Key == word)
{
d.Values[i] += 1;
}
}
or
for (int i = 0; i < d.Count; i++)
{
if (d.ElementAt(i).Key == word)
{
var val = d.ElementAt(i).Value + 1;
d.RemoveAt(i);
d.Add(word, val);
}
}
Please modify this line and check if it works. it should.
Console.WriteLine("\t{0}:\t{1}", tempSortList.GetKey(i), tempSortList.GetByIndex(i));
to
var key = tempSortedList.Keys[i];
var value = tempSortedList.Values[i];
Console.WriteLine("\t{0}:\t{1}", key, value);

using a for loop to iterate through a dictionary

I generally use a foreach loop to iterate through Dictionary.
Dictionary<string, string> dictSummary = new Dictionary<string, string>();
In this case I want to trim the entries of white space and the foreach loop does however not allow for this.
foreach (var kvp in dictSummary)
{
kvp.Value = kvp.Value.Trim();
}
How can I do this with a for loop?
for (int i = dictSummary.Count - 1; i >= 0; i--)
{
}
what about this?
for (int i = dictSummary.Count - 1; i >= 0; i--) {
var item = dictSummary.ElementAt(i);
var itemKey = item.Key;
var itemValue = item.Value;
}
KeyValuePair<TKey, TValue> doesn't allow you to set the Value, it is immutable.
You will have to do it like this:
foreach(var kvp in dictSummary.ToArray())
dictSummary[kvp.Key] = kvp.Value.Trim();
The important part here is the ToArray. That will copy the Dictionary into an array, so changing the dictionary inside the foreach will not throw an InvalidOperationException.
An alternative approach would use LINQ's ToDictionary method:
dictSummary = dictSummary.ToDictionary(x => x.Key, x => x.Value.Trim());
You don't need to use .ToArray() or .ElementAt(). It is as simple as accessing the dictionary with the key:
dictSummary.Keys.ToList().ForEach(k => dictSummary[k] = dictSummary[k].Trim());

Loop inside a array within a dictionary

Hi I have a quick question, which is the easiest way to loop inside an array that is within an object in a dictionary using C#?
The dictionary contain groups and groups have an array called tags, I have search for a tag and return a list of groups that contain that tag
I created a solution but it returns too many doubles when I apply it.
List<Programme> toReturn = new List<Programme>();
// might need to ask getprogramme service to do the iteriation and retun a value
foreach (Programme programme in programmes.Values)
{
if (message.Programme.Tags[0] != null)
{
int i;
int u;
foreach (KeyValuePair<string, Programme> entry in programmes)
{
// for (i = 0; i < message.Group.Tags.Length; i++)
for (i = 0; i < entry.Value.Tags.Length; i++)
//foreach (string i in message.Group.Tags)
{
for (u = 0; u < message.Programme.Tags.Length; u++)
{
// Compare the Name of the entry to the Name in the message (string comparison)
if (entry.Value.Tags[i].Equals(message.Programme.Tags[u]))
{
// If we found the group, set the return value and then break from the loop
toReturn.Add(programme);
break;
}
}
}
}
}
The easiest way is to use LINQ:
var res = groups.Where(g => g.Value.Any(t => t.Equals("search_tag")));

How to skip a specific position within a for each loop in c sharp?

List<string> liste = new List<String>
{
"A","B","C","D"
};
foreach (var item in liste)
{
System.Diagnostics.Debug.WriteLine(item.ToString());
}
for (int i = 0; i < liste.Count; i++)
{
if (i == 0)
continue;
System.Diagnostics.Debug.WriteLine(liste[i].ToString());
}
How do i skip a specific position in a foreach loop? I do not want to evaluate any values, but just skip the position x.
It has to be a specific position. One could choose position 0 or maybe position 7.
It is very easy to skip the first item in the list:
foreach(var item in list.Skip(1))
{
System.Diagnostics.Debug.WriteLine(item.ToString());
}
If you want to skip any other element at index n, you could write this:
foreach(var item in list.Where((a,b) => b != n))
{
System.Diagnostics.Debug.WriteLine(item.ToString());
}
In this example I use a lambda expression that takes two arguments: a and b. Argument a is the item itself, while argument b is the index of the item.
The relevant pages on MSDN that describe these extension methods are:
IEnumerable.Skip()
IEnumerable.Where()
You could even write your own extension method that allows you to skip an element in a list:
public static class MyEnumerableExtensions
{
public static IEnumerable<T> SkipAt<T>(this IEnumerable<T> list, int index)
{
var i = 0;
foreach(var item in list)
{
if(i != index)
yield return item;
i++;
}
}
}
This will allow you to write something like this to skip an item:
foreach(var item in list.SkipAt(2))
{
System.Diagnostics.Debug.WriteLine(item.ToString());
}
A foreach loop iterates over a collection that implements IEnumerable. The enumerator exposes the current item and a method to move onto the next item - it has no concept of an index.
You could always do:
var i = 0;
foreach (var item in liste) {
if (i++ == skip) continue;
Debug.WriteLine(item.ToString());
}
But this seems unnecessarily contrived. If you need an index, go with a for loop.
The other option is to remove the undesired item from the List before iterating:
foreach (var item in liste.Take(n-1).Union(liste.Skip(n))) {
Debug.WriteLine(item.ToString());
}
I love list's .ForEach, here's my take using #Elian's .SkipAt(n) and .ForEach:
var list = new List<String> { "A", "B", "C", "D" };
list = list.SkipAt(1).ToList();
list.ForEach(Debug.WriteLine);
You should try using the enhanced version of the Where extension method that allows you to filter on item and index.
Check the reference.
http://msdn.microsoft.com/en-us/library/bb549418.aspx
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Verbatim list");
List<string> list = new List<String> { "A","B","C","D" };
foreach (var item in list)
{
Console.WriteLine(item.ToString());
}
Console.WriteLine("Filtered list");
int itemToSkip = 2;
foreach (var item in list.Where((item, index) => index != itemToSkip))
{
Console.WriteLine(item.ToString());
}
Console.ReadKey();
}
}
}
This will give you the following output.
Verbatim list
A
B
C
D
Filtered list
A
B
D
To skip a position inside the foreach loop, one option is that you can skip the action inside the foreach loop by using an if statement, like
foreach(var item in liste)
{
if (item != 'X')
{
//do something
}
}
But i am waiting for better solutions

Categories