0

How do I use two foreach's on one table, or another method to get my count and total together?

This is the table:

<div style="padding-top: 30px">
    <table id="table_id" class="display">
        <thead>
            <tr>
                <th>Month</th>
                <th>Count</th>
                <th>Total</th>
            </tr>
        </thead>
        <tbody>
            @foreach (var item in Model.Date1.Reverse())
        {
                <tr>
                    <td> @Html.DisplayFor(modelItem => item.theDate) </td>
                    <td> @Html.DisplayFor(modelItem => item.theCount) </td>
                </tr>
            }
            @foreach (var item in Model.Date2.Reverse())
        {
                <tr>
                    <td></td>
                    <td></td>
                    <td> @Html.DisplayFor(modelItem => item.theCount) </td>
                </tr>
            }

        </tbody>
    </table>
    </div>

This is how I'm calling the models:

    public class QueryView
    {
        public IEnumerable<Date1> Date1 { get; set; }
        public IEnumerable<Date1> Date2 { get; set; }
    }
}
@model CWebPortal.Models.QueryView

This is what is displayed: table

I want that Total to be on the same line of course.

Thanks!

Community
  • 1
  • 1
Stem Step
  • 61
  • 1
  • 12

4 Answers4

2

You need to iterate through the list in parallel.

hope these links will help

  1. iterate simultaneously through multiple list
  2. Iterate two Lists or Arrays with one ForEach statement in C#
@using (var e1 = Model.Date1.Reverse().GetEnumerator()) { using (var e2 = Model.Date2.Reverse().GetEnumerator()) { while (e1.MoveNext() && e2.MoveNext()) { var item1 = e1.Current; var item2 = e2.Current; item1.theDate item1.theCount item2.theCount } } }
Community
  • 1
  • 1
Shamseer K
  • 4,964
  • 2
  • 25
  • 43
0

You could convert your two foreach loops into one for loop and use the same index for both IEnumerables. That's probably the first, and simplest, step to correcting the issue.

As a second step, I'd suggest looking for ways to rewrite this Model. If these three pieces of data are related this closely, then there's plenty of reason for you to create a new object that contains all the data.

Lastly, the View reversing the order of the items in the IEnumerables strikes me as a code smell. This kind of newest-to-oldest sorting, particularly done across two enumerable objects, could easily be in the Model as well.

jwheron
  • 2,553
  • 2
  • 30
  • 40
  • How do I rewrite the model so the data is together? – Stem Step Sep 13 '16 at 13:08
  • We'd need way more detail to answer that question. Start with your data source - those three columns came from somewhere, so try to rewrite the code that retrieves the data so that all three columns go into one object. – jwheron Sep 13 '16 at 14:05
0

In the model, you can add another list with a class Table, which will have all three values. Something like below.

public IEnumerable<Table> TableLst { get; set; }

public class Table
{
    public DateTime Date { get; set; }
    public int count { get; set; }
    public int total { get; set; }
}

As you have two lists Date1 and Date2, you can easily join these based on dates using LINQ and pass it in the controller.

 var data = qv.Date1.Join(qv.Date2, d1 => d1.theDate, d2 => d2.theDate, (d1, d2) => new { d1, d2 });

        qv.Table = data.Select(t => new Table
        {
            Date = t.d1.theDate,
            count = t.d1.theCount,
            total = t.d2.theCount

        });

        return View(qv);

You can also perform order by on the TableLst in the controller and pass it to model. After which only one for loop would be easy to get the data

  @foreach (var item in Model.TableLst)
        {
            <tr>
                <td> @Html.DisplayFor(modelItem => item.Date) </td>
                <td> @Html.DisplayFor(modelItem => item.count) </td>
                <td> @Html.DisplayFor(modelItem => item.total) </td>
           </tr>
        }
Nagashree Hs
  • 843
  • 6
  • 18
0

Use an intermidiate viewModel class to group the data.

e.g.

public class QueryViewModel
{
    public DateTime displayDate {get; set;}
    public int Count1 {get; set;}
    public int count2 {get; set;}
}

 public class QueryView
 {
    public IEnumerable<QueryViewModel> DateList =new IEnumerable<QueryViewModel>();
    public IEnumerable<Date1> Date1 { get; set; }
    public IEnumerable<Date1> Date2 { get; set; }

    public  fillDates()
    {
       QueryViewModel qvm=new QueryViewModel()          
       int i=0;
       foreach(var item in Date1.Reverse())
       {
          qvm.displayDate = theDate;
          qvm.Count1  = theCount;
         DateList.Add(qvm);
       }

       int i=0;
       foreach(var item in Date2.Reverse())
       {
          DateList[i].Count2  = theCount;
          i++;
       }

       return DateList
    }
 }

Use fillDates() in your view to render the list.

Abhishek Pandey
  • 338
  • 1
  • 3
  • 13