在return语句中按名字的第一个字母分组

时间:2013-09-10 14:20:23

标签: c# asp.net-mvc linq

我正在返回一个声明,该声明会让许多用户显示所有已按字母顺序排列的用户。我想显示这个结果还增加了它能够将所有以相同字母开头的名称组合在一起,这样我就可以为它创建某种标签或索引。

代码:

return new UserService().GetUsers(id.Value, pageNumber: _pageNum).GroupBy(x=>x.Name.Substring(0,1));

问题:return语句抛出错误说明:

Cannot implicitly convert type 'System.Collections.Generic.IEnumerable<System.Linq.IGrouping<string,ProjectName.Shared.Models.Views.User>>' to 'System.Collections.Generic.IEnumerable<ProjectName.Shared.Models.Views.User>'. An explicit conversion exists (are you missing a cast?)  

我该如何解决这个问题?

4 个答案:

答案 0 :(得分:2)

问题是该语句创建了一个分组,但您试图返回一个普通的用户列表。

有两种解决方法:

  • 您可能希望返回IDictionary<string,IList<User>>而非IEnumerable<User>(您也可以使用char作为关键字)或
  • 如果要返回普通列表,您可能希望按名称订购用户,而不是分组。

以下是如何将其设为IDictionary<string,IList<User>>

IDictionary<string,IList<User>> res = new UserService()
    .GetUsers(id.Value, pageNumber: _pageNum)
    .GroupBy(x=>x.Name.Substring(0,1))
    .ToDictionary(
        g => g.Key
    ,   g => (IList<User>)g.ToList()
    );

编辑:(响应此评论:“我想分组,以便所有以A开头的名称都在A标题下,依此类推,所以我只是改变了外观并没有真正排序“)

在这种情况下,您不需要 分组(尽管如果您希望这样做,您当然可以使用它)。您可以在LINQ中,在SP中或其他方式对数据进行排序,然后通过插入以不同字母开头的名称之间的边界来直观地提供标题。

这是在打印到控制台的程序中执行此操作的一个非常粗略的示例。您应该能够通过很少的工作使其适应您的特定视觉效果:

// I assume that you know how to write the GetUsersSortedByName method
IList<User> sortedUsers = GetUsersSortedByName();
char? lastSeenFirstLetter = null;
// The loop below assumes that there are no users with empty names
foreach (User u in sortedUsers) {
    if (u.Name[0] != lastSeenFirstLetter) {
        Console.WriteLine("==== Header: users with names in {0}", u.Name[0]);
        lastSeenFirstLetter = u.Name[0];
    }
    Console.WriteLine(u); // Finally, display the user
}

答案 1 :(得分:1)

您需要从方法中返回相应的类型:

public IEnumerable<IGrouping<string, User>> GetUserIndex()
{
    return new UserService().GetUsers(id.Value, pageNumber: _pageNum).GroupBy(x=>x.Name.Substring(0,1));
}

然后你可以像这样迭代每个组:

var userIndex = GetUserIndex();

foreach(var group in userIndex)
{
    string currentLetter = group.Key;
    foreach(User user in group)
    {
        //do something
    }
}

答案 2 :(得分:0)

  

问题:return语句抛出错误说明:

     

Cannot implicitly convert type 'System.Collections.Generic.IEnumerable<System.Linq.IGrouping<string,ProjectName.Shared.Models.Views.User>>' to 'System.Collections.Generic.IEnumerable<ProjectName.Shared.Models.Views.User>'. An explicit conversion exists (are you missing a cast?)

     

我该如何解决这个问题?

试试这个:

    return new UserService()
            .GetUsers(id.Value, pageNumber: _pageNum)
            .GroupBy(x=>x.Name.Substring(0,1))
            .Select(g=>g); //<-----

答案 3 :(得分:0)

你说你有一个方法,你希望它返回这样的东西:

return new UserService()
         .GetUsers(id.Value, pageNumber: _pageNum)
         .GroupBy(x=>x.Name.Substring(0,1));

根据您获得的编译器错误,很明显您的方法看起来像这样:

public IEnumerable<ProjectName.Shared.Models.Views.User> GetTheUsers() {
    // do something here...

    return new UserService()
             .GetUsers(id.Value, pageNumber: _pageNum)
             .GroupBy(x=>x.Name.Substring(0,1));
}

你做不到。保留它就像你最初设计它,没有分组:

public IEnumerable<ProjectName.Shared.Models.Views.User> GetTheUsers() {
    // do something here...

    return new UserService().GetUsers(id.Value, pageNumber: _pageNum);
}

然后,当你调用它时,在现场进行分组:

public void Foo() {
    // do something here...

    var ungroupedUsers = GetTheUsers();

    var groupedUsers = ungroupedUsers.GroupBy(x=>x.Name.Substring(0,1))

    // and now use the groupedUsers accordingly

}