0

Hi all and thanks in advance,

I have a question about how (or if) the following should be done. I have a list of items being returned and for certain pieces I am using a string.join to compile those parts into a single string on the page but now I need to add line numbers to this display.

Currently this is how the data is displaying and how I want it to look after numbers are added:

 Title (before)             Title (after)
  ---------                 ---------
  Book1                     1. Book1
  Book2                     2. Book2

The data is being displayed in a List View in a single Eval statement for each item (Title,Program) like so:

 <asp:ListView runat="server" ID="lvResults" AutoGenerateColumns="False" ItemPlaceholderID="resultsPlaceHolder">
      <EmptyDataTemplate>
           <div style="width: 100%; text-align: center;">No results available.</div>
      </EmptyDataTemplate>
      <LayoutTemplate>
           <table id="tblResults" summary="">
               <tbody>
                    <asp:PlaceHolder runat="server" ID="resultsPlaceHolder"></asp:PlaceHolder>
               </tbody>
           </table>
      </LayoutTemplate>
      <ItemTemplate>
           <tr>
               <td>
                    Text: <%# Eval("Text") %><br/>
                    Description: <%# Eval("Description") %><br/>
                    <br class="clear"/>
               </td>
               <td>
                    Title<br/><%# Eval("Title") %>
               </td>
               <td>
                    Program<br/><%# Eval("Value") %>
               </td>
            </tr>
      </ItemTemplate>
   </asp:ListView>

I'm populating the List View with this:

List<MyBooks> newBooklist = oldBookList.Select(i => new MyBooks()
    {
        Id = i, 
        Text = oldBookList.Where(o => o.Id == i).Select(o => o.Text).FirstOrDefault(),
        Description = oldBookList.Where(o => o.Id == i).Select(o => o.Description).FirstOrDefault(), 
        //tried getting index here but output is wrong "{ index = 0, title = .. }"
        Title = string.Join("<br/>", oldBookList.Where(o => o.Id == i).Select((o,index) => new { index, o.Title  }).Distinct()), 
        Value = string.Join("<br/>", oldBookList.Where(o => o.Id == i).Select(o => o.Value).Distinct()), 
    }).ToList();

I'd like to fix the above so that I can add in the numbers into the text as part of the string.join operation. To that end, I tried following suggestions here How To Project a Line Number Into Linq Query Result and here How to get index using LINQ? [duplicate] but both examples seem to deal with have a separate property to dump the value into which I don't have in my scenario.

Another idea that I found was to consider looping through the list Titles and adding the text before I pull this list that populates the List View but I'm concerned that would be an expensive operation, would it be?

The one thing I would really prefer not to do is to add these numbers to the SQL query because this query is used in other places.

[UPDATE]

As asked in the comment below, I wanted to have numbers but I needed the numbers to further subgroup by Title and Program. The best way to achieve this finally turned out to be just iterating through the list before hand with a foreach statement to set the numbers.

    int dt = 0;
    int oldId = 0;
    foreach (var d in oldList)
    {
        if (oldId != d.Id)
        {
            dt = 0;
            oldId = d.Id;
        }
        dt++;
        d.Title = dt + ". " +  d.Title;
        d.Program = dt + ". " + d.Program;
    }
Community
  • 1
  • 1
Elaine K
  • 507
  • 2
  • 7
  • 32

2 Answers2

1

Using enumerable.Range should get you what you want.

List<MyBooks> newBooklist = from i in Enumerable.Range(0, oldBookList.Count)
{
    Id = i, 
    Text = oldBookList[i].Text,
    Description = oldBookList[i].Description, 
    ....

}).ToList();

You use the select overload in your OP, so I assumed that you knew about it. But in that format it would look like this:

List<MyBooks> newBooklist = oldBookList.Select((book, i) => new MyBooks()
{
    Id = i, 
    Text = book.Text,
    Description = book.Description, 
    ....

}).ToList();
crthompson
  • 15,653
  • 6
  • 58
  • 80
  • Both of these answers have gotten me closer to my goal in that now I'm able to have the numbers where I want them but now I'm having an issue in that I have two separate lists, the Titles and the Programs and its number as an example 1-22 for both when what I need is for Titles to be numbered 1-9 and Programs to be numbered 1-13. Is that possible using the index in this manner? – Elaine K Sep 20 '14 at 12:16
  • @ElaineK No, not by the information you've given here. That sounds like a great second question though. You should up vote and mark answer here, and post that as a new question. It will get more attention that way anyway. – crthompson Sep 21 '14 at 15:33
1

I think Jon Skeet might have the answer for you Can I have an incrementing count variable in LINQ?

Basically there is an overload of Select that provides an index, and you can use that index in your string.Join calls.

stuff.Select((value, index) => new { index, value.Name });
Community
  • 1
  • 1
Zack
  • 2,789
  • 33
  • 60
  • Both of these answers have gotten me closer to my goal in that now I'm able to have the numbers where I want them but now I'm having an issue in that I have two separate lists, the Titles and the Programs and its number as an example 1-22 for both when what I need is for Titles to be numbered 1-9 and Programs to be numbered 1-13. Is that possible using the index in this manner? – Elaine K Sep 20 '14 at 13:56