36

I am very new to .NET, used to working in PHP. I need to iterate via foreach through a dictionary of objects. My setup is an MVC4 app.

The Model looks like this:

public class TestModels
{
    Dictionary<int, dynamic> sp = new Dictionary<int, dynamic>
    {
        {1, new {name="abc", age="1"}},
        {2, new {name="def", age="2"}}
    }
}

Controller:

public class TestController : Controller
{
   Models.TestModels obj = new Models.TestModels();
}

How do I loop through the obj object and retrieve the values of the dictionary and print them in the view?

reformed
  • 4,505
  • 11
  • 62
  • 88
user1833222
  • 403
  • 2
  • 5
  • 8
  • 2
    possible duplicate of [What is the best way to iterate over a Dictionary in C#?](http://stackoverflow.com/questions/141088/what-is-the-best-way-to-iterate-over-a-dictionary-in-c) – Jeremy Feb 06 '13 at 01:17
  • 2
    (I voted as a duplicate as well: just keep in mind that iteration order is not defined ..) –  Feb 06 '13 at 01:19

4 Answers4

55

One way is to loop through the keys of the dictionary, which I recommend:

foreach(int key in sp.Keys)
    dynamic value = sp[key];

Another way, is to loop through the dictionary as a sequence of pairs:

foreach(KeyValuePair<int, dynamic> pair in sp)
{
    int key = pair.Key;
    dynamic value = pair.Value;
}

I recommend the first approach, because you can have more control over the order of items retrieved if you decorate the Keys property with proper LINQ statements, e.g., sp.Keys.OrderBy(x => x) helps you retrieve the items in ascending order of the key. Note that Dictionary uses a hash table data structure internally, therefore if you use the second method the order of items is not easily predictable.

Update (01 Dec 2016): replaced vars with actual types to make the answer more clear.

Sina Iravanian
  • 16,011
  • 4
  • 34
  • 45
  • so is to be done in the View ? Also value will contain both the values right ? so then I just have to do value.0 and value.1 to print ? – user1833222 Feb 06 '13 at 01:19
  • No. You would do it like in my answer, or based on Sina's answer you would call it using `value` and the name you gave the variable, e.g. `value.name` or `value.age`. – eandersson Feb 06 '13 at 01:40
  • 2
    small point: it'd make this a little easier to understand if the var keyword wasn't used – Jezzamon Feb 13 '15 at 06:10
4

It depends on what you are after in the Dictionary

Models.TestModels obj = new Models.TestModels();

foreach (var keyValuPair in obj.sp)
{
    // KeyValuePair<int, dynamic>
}

foreach (var key in obj.sp.Keys)
{
     // Int 
}

foreach (var value in obj.sp.Values)
{
    // dynamic
}
nim
  • 140
  • 2
  • 9
sa_ddam213
  • 42,848
  • 7
  • 101
  • 110
1

You can do it like this.

Models.TestModels obj = new Models.TestModels();
foreach (var item in obj.sp)
{
    Console.Write(item.Key);
    Console.Write(item.Value.name);
    Console.Write(item.Value.age);
}

The problem you most likely have right now is that the collection is private. If you add public to the beginning of this line

Dictionary<int, dynamic> sp = new Dictionary<int, dynamic> 

You should be able to access it from the function inside your controller.

Edit: Adding functional example of the full TestModels implementation.

Your TestModels class should look something like this.

public class TestModels
{
    public Dictionary<int, dynamic> sp = new Dictionary<int, dynamic>();

    public TestModels()
    {
        sp.Add(0, new {name="Test One", age=5});
        sp.Add(1, new {name="Test Two", age=7});
    }
}

You probably want to read up on the dynamic keyword as well.

eandersson
  • 25,781
  • 8
  • 89
  • 110
0
public class TestModels
{
    public Dictionary<int, dynamic> sp = new Dictionary<int, dynamic>();

    public TestModels()
    {
        sp.Add(0, new {name="Test One", age=5});
        sp.Add(1, new {name="Test Two", age=7});
    }
}
LarsTech
  • 80,625
  • 14
  • 153
  • 225
  • 2
    Your answer certainly is worth a little explanation. Kindly refer to http://stackoverflow.com/help/how-to-answer . – J. Chomel Sep 22 '16 at 06:25