Greetings all. In my MVC app I am trying to iterate through 2 collections, which are similar to a jagged array (a collection of modules, each containing a collection of components). Module and Component each have an Index attribute where the sort order is specified through an admin tool. The flow:
1) Get the user's assigned presentation (pid)
2) Get the modules contained in the pid (mndx), indexed ascending - set index variable
3) Get the components in each mndx, indexed ascending - set index variable
4) Get module index 1 - iterate from component index 1 to last index
5) Iterate to module index 2 - iterate from component index 1 to last index
6) Pass iteration of mIndex and iteration of cIndex in TempData to PartialView Controller action for rendering.
7) ...Rinse and repeat through modules and components until done

My code is below - can anyone see a way to do this? (I know I can't convert Components ToList, but I am stuck).

                var Modules = db.PresentationModules
                .Where(m => m.PresentationId == pid)
                .OrderBy(m => m.ModuleIndex)
                .Select(m => m.ModuleIndex)
                .ToList();

                List<ModuleComponent> Components = new List<ModuleComponent>();
                foreach (int mndx in Modules)
                {
                    Components = db.ModuleComponents
                    .OrderBy(m => m.ComponentIndex)
                    .Select(m => m.ComponentIndex)
                   .ToList();
                }

                for (int i = 0; i < Modules.Count; i++)
            {
                mIndex = i;
                    for (int c = 0; c < Components.Count; c++)
                {
                    cIndex = c;
                }
            }

Recommended Answers

All 10 Replies

I can think of several ways to do this, but more detail would help. What is this algorithm ultimately doing? Describing what you want to accomplish rather than how you want to accomplish it works better when looking for alternative methods.

Thanks for your response. The end result (what this code is to accomplish) is an AjaxAction to replace a div with the partialview generated by steps 1-7 in my post.
Each user has his/her own assigned presentation, which contains modules (Welcome, Benefits, Safety, etc.), and each module contains components (HTML rendering audio, video, form, quiz, PDF, etc.). This is different for each user, so I need to systematically loop through each module and its components dynamically based on the user's presentation.

I might organize my database so that I could do something like this:

var presentation = from m in db.PresentationModules
                   where m.PresentationId = pid
                   orderby m.ModuleIndex
                   select new
                   {
                       Module = m,
                       Components = from c in db.ModuleComponents
                                    where c.ModuleIndex = m.ModuleIndex
                                    orderby c.ComponentIndex
                   };

That way I could select a collection of modules and module components tied to the user. The collection can then be used in a more convenient manner than diddling around with indexes.

commented: Indeed eternally awesome! +14

Two reasons I can't really set it up that way:
1) Both Modules and Components have their own indexes because they are in different orders for different users

2) I need to keep separate statuses on both the current Module and the current Component, to drive a progress bar on both Modules and Components

Modules and Component are already tied to the user, just through 2 tables.

How exactly is your database structured?

Presentation, Module and Component are each standard (id, title, etc.), but here are the join tables:

    public class PresentationModule
    {
        [Key]
        public int PresentationModuleId { get; set; }
        public int PresentationId { get; set; }
        public int ModuleId { get; set; }
        public int ModuleIndex { get; set; }
    }

    public class ModuleComponent
    {
        [Key]
        public int ModuleComponentId { get; set; }
        public int ModuleId { get; set; }
        public int ModuleIndex { get; set; }
        public int ComponentId { get; set; }
        public int ComponentIndex { get; set; }
    }

I should add that the User simply gets assigned a PresentationId - everything else stems from that.

How do the indexes relate in those two join tables? Can you show me an example of what the data might look like?

I don't know if this helps, but the joins are just to link the indexes and ids.
Each line below is what a single user click should return as iterations:
(userClick) Module 1, Component1
(userClick) Module 1, Component2
(userClick) Module 1, Component3
etc...
(userClick) Module 2, Component1
(userClick) Module 2, Component2
(userClick) Module 2, Component3
etc...
(userClick) Module 3, Component1
etc...

The data is based on the ComponentId, looked up by ComponentIndex.
ComponentId entities have the attributes (ComponentType, ComponentUrl, etc...) that are passed to the PartialView to be rendered.

I figured it out. Code below.

                var Modules = db.PresentationModules
                .Where(m => m.PresentationId == pid)
                .OrderBy(m => m.ModuleIndex)
                .Select(m => m.ModuleId)
                .ToArray();

                for (int i = 1; i < Modules.Length; i++)
                {
                    mIndex = i; //initialized earlier to bridge scope
                    Components = db.ModuleComponents //initialized earlier to bridge scope
                    .Where(m => m.ModuleIndex == mIndex)
                    .OrderBy(m => m.ComponentIndex)
                    .Select(m => m.ComponentIndex)
                    .ToArray();

                    for (int c = 1; c < Components.Length; c++)
                    {
                        cIndex = c; //initialized earlier to bridge scope
                    }
                }

This question was not answered by deceptikon - I figured it out myself.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.