使用带有String.Join的Linq select插入行号

时间:2014-09-19 21:48:17

标签: c# linq

大家好,并提前致谢,

我有一个关于如何(或是否)应该做以下事情的问题。我有一个返回的项目列表,对于某些部分我使用string.join将这些部分编译成页面上的单个字符串,但现在我需要在此显示中添加行号。

目前这是数据的显示方式以及添加数字后我希望它如何显示:

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

数据正在列表视图中显示在每个项目(标题,程序)的单个Eval语句中,如下所示:

 <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>

我用这个填充列表视图:

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();

我想修复上述问题,以便我可以将数字作为string.join操作的一部分添加到文本中。为此,我尝试了以下How To Project a Line Number Into Linq Query ResultHow to get index using LINQ? [duplicate]的建议,但这两个示例似乎都有一个单独的属性来转储我在我的方案中没有的价值。

我发现的另一个想法是考虑循环列表标题并添加文本,然后我拉出填充列表视图的列表,但我担心这将是一项昂贵的操作,是不是?

我真的不想做的一件事是将这些数字添加到SQL查询中,因为此查询在其他地方使用。

[UPDATE]

正如下面的评论所述,我想要数字,但我需要按标题和程序进一步分组的数字。实现这一目标的最佳方法最终只是通过foreach语句迭代遍历列表来设置数字。

    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;
    }

2 个答案:

答案 0 :(得分:1)

使用enumerable.Range可以得到你想要的东西。

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

}).ToList();

你在OP中使用select重载,所以我假设你知道它。但在那种格式中,它看起来像这样:

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

}).ToList();

答案 1 :(得分:0)

我认为Jon Skeet可能会为你找到答案Can I have an incrementing count variable in LINQ?

基本上有Select的重载提供索引,你可以在string.Join调用中使用该索引。

stuff.Select((value, index) => new { index, value.Name });