C# 使用Linq根据属性对对象列表进行分组?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/14654056/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-10 12:35:09  来源:igfitidea点击:

Group List of Objects based on Property using Linq?

c#linqlist

提问by BlueBird

I have an object:

我有一个对象:

public class SiteInfo
        {
            public string Title { get; set; }
            public string URL { get; set; }
            public string Type { get; set; }     
        }

That I am using to create a list: var sites = new List();

我用来创建一个列表: var sites = new List();

        foreach (SPWeb site in web.GetSubwebsForCurrentUser())
        {
            string sitetype = getConfigurationKey(site, "siteType");
            //If sites have a site type then add to list
            if (sitetype != "*ERROR*" && sitetype != "*KEYNOTFOUND*")
            {
                SiteInfo s = new SiteInfo();
                s.Title = site.Title;
                s.URL = site.Url;
                s.Type = sitetype;

                sites.Add(s);
            }
        }
        //sort list by type
        sites.Sort((x, y) => string.Compare(x.Type, y.Type));

        // serialize and send..    
        JavaScriptSerializer serializer = new JavaScriptSerializer();
        StringBuilder sbJsonResults = new StringBuilder();
        serializer.Serialize(sites, sbJsonResults);
etc.....

However what I would like to do is group the sites by Type prior to serializing them. Is this possible using LINQ or some other method.

但是,我想做的是在序列化站点之前按类型对站点进行分组。这是否可以使用 LINQ 或其他一些方法。

采纳答案by Jon Skeet

It sounds like you want something like:

听起来你想要这样的东西:

// No need to sort sites first
var grouped = sites.OrderBy(x => x.Type)
                   .GroupBy(x => x.Type);

Then just serialize grouped. However, I don't know quite what an IGroupingwill look like in JSON... and the type will be present in each case. You maywant something like:

然后只需序列化grouped. 但是,我不太清楚IGroupingJSON 中的 will 是什么样子......并且类型将出现在每种情况下。你可能想要这样的东西:

var grouped = sites.OrderBy(x => x.Type)
                   .GroupBy(x => x.Type)
                   .Select(g => new { Type = g.Key,
                                      Sites = g.Select(site => new {
                                                           site.Title,
                                                           site.URL
                                                       } });

I thinkthat would give you a nicer JSON structure.

认为这会给你一个更好的 JSON 结构。

回答by I4V

This

这个

var sites = new List<SiteInfo>()
{
    new SiteInfo(){Title="1",Type="a",URL="http://aaaa"},
    new SiteInfo(){Title="2",Type="b",URL="http://bbbb"},
    new SiteInfo(){Title="3",Type="a",URL="http://aaaa"},
    new SiteInfo(){Title="4",Type="b",URL="http://bbb"},
};

var json = new JavaScriptSerializer().Serialize(sites.GroupBy(s => s.Type));

would produce

会产生

[
    [{"Title":"1","URL":"http://aaaa","Type":"a"},{"Title":"3","URL":"http://aaaa","Type":"a"}],
    [{"Title":"2","URL":"http://bbbb","Type":"b"},{"Title":"4","URL":"http://bbb","Type":"b"}]
]

or

或者

var json = new JavaScriptSerializer().Serialize(sites.GroupBy(s => s.Type)
                                                      .ToDictionary(x=>x.Key,x=>x));

would produce

会产生

{
    "a":[{"Title":"1","URL":"http://aaaa","Type":"a"},{"Title":"3","URL":"http://aaaa","Type":"a"}],
    "b":[{"Title":"2","URL":"http://bbbb","Type":"b"},{"Title":"4","URL":"http://bbb","Type":"b"}]
}

回答by Leniel Maccaferri

Here's a straightforward console application that does what you want:

这是一个简单的控制台应用程序,可以执行您想要的操作:

static void Main(string[] args)
{
    List<SiteInfo> sites = new List<SiteInfo>()
    {
        new SiteInfo() { Title = "Site A", Type = "Whatever 2" },
        new SiteInfo() { Title = "Site B", Type = "Whatever 1" },
        new SiteInfo() { Title = "Site C", Type = "Whatever 1" },
        new SiteInfo() { Title = "Site D", Type = "Whatever 3" },
        new SiteInfo() { Title = "Site E", Type = "Whatever 3" }
    };

    var sitesGroupedByType =
        sites.GroupBy(s => s.Type).Select(g => new { Type = g.Key,
                                    Sites = g.Select(site => new
                                    {
                                          site.Title,
                                          site.URL
                                    })});

    foreach (var siteTypeGroup in sitesGroupedByType.OrderBy(g => g.Type))
    {
        foreach(var site in siteTypeGroup.Sites)
        {
            Console.WriteLine(string.Format("Type => {0}, Title => {1}",
                              siteTypeGroup.Type, site.Title));
        }
    }

    Console.ReadKey();
}

Output:

输出:

Type => Whatever 1, Title => Site B
Type => Whatever 1, Title => Site C
Type => Whatever 2, Title => Site A
Type => Whatever 3, Title => Site D
Type => Whatever 3, Title => Site E