public class ConsolidatedChild
{
    public string School { get; set; }
    public string Friend { get; set; }
    public string FavoriteColor { get; set; }
    public List<Child> Children { get; set; }
}

public class Child
{
    public string School { get; set; }
    public string Name { get; set; }
    public string Address { get; set; }
    public string Friend { get; set; }
    public string Mother { get; set; }
    public string FavoriteColor { get; set; }
}


鉴于以上两个类,我想使用LINQ从列表中创建一个列表,该列表按School,Friend和FavoriteColor属性进行分组。

请忽略属性,编写代码只是为了帮助解决这个问题。

评论

对的,这是可能的。看一下这篇文章中提供的示例。

这是另一个很好的例子stackoverflow.com/questions/15605468 / ...

#1 楼

容易:

var consolidatedChildren =
    from c in children
    group c by new
    {
        c.School,
        c.Friend,
        c.FavoriteColor,
    } into gcs
    select new ConsolidatedChild()
    {
        School = gcs.Key.School,
        Friend = gcs.Key.Friend,
        FavoriteColor = gcs.Key.FavoriteColor,
        Children = gcs.ToList(),
    };



var consolidatedChildren =
    children
        .GroupBy(c => new
        {
            c.School,
            c.Friend,
            c.FavoriteColor,
        })
        .Select(gcs => new ConsolidatedChild()
        {
            School = gcs.Key.School,
            Friend = gcs.Key.Friend,
            FavoriteColor = gcs.Key.FavoriteColor,
            Children = gcs.ToList(),
        });


评论


假设我在分组依据中有很多属性,是否有更干净的方法来列出所有属性?

– Guiomie
15年8月21日在18:35

@guiomie-我不会说有一种更清洁的方法。您可以将对象序列化为单个字符串并在其上分组,但这将需要在其他地方添加更多代码。因此,在我看来,无论有多少属性,此答案都是最干净的方法。

–谜题
15年8月21日在23:03



@Doppelganger-我回滚您的编辑有两个原因。选择使用最后一个逗号(在FavoriteColor之后)是有目的的-这是合法的语法,它使代码重构更加容易。使用gcs而不是gc进行分组变量的选择也是有目的的-它向我表明这是“许多c的组”。

–谜题
15年11月28日在1:05

我以为肯定不会编译,但是您绝对正确。至于重命名变量,那仅仅是为了超过六个字符的限制。我从不喜欢弄乱某人的变量名。无论如何,再次感谢您的出色回答!

–Doppelganger
2015年11月30日20:16



@AlexanderRyanBaggett-完成。

–谜题
19年2月12日在22:17

#2 楼

给定一个列表:

var list = new List<Child>()
{
    new Child()
        {School = "School1", FavoriteColor = "blue", Friend = "Bob", Name = "John"},
    new Child()
        {School = "School2", FavoriteColor = "blue", Friend = "Bob", Name = "Pete"},
    new Child()
        {School = "School1", FavoriteColor = "blue", Friend = "Bob", Name = "Fred"},
    new Child()
        {School = "School2", FavoriteColor = "blue", Friend = "Fred", Name = "Bob"},
};


查询如下:

var newList = list
    .GroupBy(x => new {x.School, x.Friend, x.FavoriteColor})
    .Select(y => new ConsolidatedChild()
        {
            FavoriteColor = y.Key.FavoriteColor,
            Friend = y.Key.Friend,
            School = y.Key.School,
            Children = y.ToList()
        }
    );


测试代码:

foreach(var item in newList)
{
    Console.WriteLine("School: {0} FavouriteColor: {1} Friend: {2}", item.School,item.FavoriteColor,item.Friend);
    foreach(var child in item.Children)
    {
        Console.WriteLine("\t Name: {0}", child.Name);
    }
}


结果:

School: School1 FavouriteColor: blue Friend: Bob
    Name: John
    Name: Fred
School: School2 FavouriteColor: blue Friend: Bob
    Name: Pete
School: School2 FavouriteColor: blue Friend: Fred
    Name: Bob


评论


对于那些喜欢流畅界面的人。一个小小的错误:对于新用户来说,在两个Func定义中使用相同的变量“ x”并不是很清楚。我建议更改为与上面的匹配,其中“ c”是子级,“ gcs”是分组的子级。

–迈克尔·布莱克本
2012年11月19日15:46



@jazmatician _我同意您的观点,即重复使用x可能会使某些人混淆,但对于变量名的选择却没有。我将其更改为x和y进行微分。

–贾米茨
2012年11月19日15:51

变量名也不是我的选择。实际上,在撰写本文时,我努力弄清楚“ gcs”对作者的意义。我能想到的最好的是“ CS组”。无论如何,我仅推荐它尝试使某人易于在两种语法之间建立思维导图。 (句法?我敢打赌语法是那些单词中的一个,它是自己的复数形式。因为这是英文,所以“语法”为什么要服从关于复数的句法规则?)

–迈克尔·布莱克本
2012年11月19日下午16:51

回答我自己的切线:en.wiktionary.org/wiki/syntax

–迈克尔·布莱克本
2012年11月19日下午16:51

我不同意迈克尔的这一观点。我认为x应该在两个地方都使用。唯一不应该的情况是将Func与另一个Hunc一起使用时,应转到y。否则会造成混乱。

–塞尔吉·萨根(Serj Sagan)
14年10月30日在16:17