C#聚合列表中的属性

时间:2016-06-01 07:40:34

标签: c# linq

我有一个如下所示的对象

public class SampleObject
{
    public int MsfId { get; set; }
    public List<string> PgId { get; set; }
    public List<string> DcId { get; set; }
}

在由PgId分组的MsfId值的上述聚合中。同样是DcId的情况。

例如:

MsfId: 100
PgId: "abc"
DcId: "123"

MsfId: 100
PgId: "def"
DcId: "456"

MsfId: 100
PgId: "ghi"
DcId: "789"

MsfId: 101
PgId: "abc"
DcId: "123"

如何编写LINQ查询来聚合它并创建一个SampleObjects列表,如下所示?

MsfId: 100
PgId: "abc", "def", "ghi"
DcId: "123", "456", "789"

MsfId: 101
PgId: "abc"
DcId: "123"

4 个答案:

答案 0 :(得分:7)

尝试这样的聚合:

var result = col.GroupBy(x => x.MsfId)
                .Select(x => new SampleObject {
                       MsfId = x.Key, 
                       PgCodes = x.Select(t=>t.PgId).ToList(),
                       DcCodes = x.Select(t=>t.DcId).ToList()
                });

答案 1 :(得分:4)

情景1

public class SampleObject
{
    public int MsfId { get; set; }
    public List<string> PgId { get; set; }
    public List<string> DcId { get; set; }
}

情景2

public class SampleObjectSource
{
    public int MsfId { get; set; }
    public string PgId { get; set; }
    public string DcId { get; set; }
}

场景1回答

   var collection = new List<SampleObject>();
   var result = collection.GroupBy(y => y.MsfId)
                    .Select(y => new SampleObject
                    {
                        MsfId = y.Key,
                        PgId = y.SelectMany(g => g.PgId).Distinct().ToList(),
                    }).ToList();

场景2

var collection2 = new List<SampleObjectSource>();
var result1 = collection2.GroupBy(y => y.MsfId)
              .Select(y => new SampleObject
              {
                  MsfId = y.Key,
                  PgId = y.Select(h => h.PgId).Distinct().ToList(),
              }).ToList();

更新:请参阅dotnetfiddle

答案 2 :(得分:3)

您需要使用查询对项目进行分组。 此linq分组将创建一个集合集合(带密钥)

我刚刚做了一个完整的例子:

// The class to start with
public class SampleObjectSource
{
    public int MsfId { get; set; }
    public string PgId { get; set; }
    public string DcId { get; set; }
}

// the result class
public class SampleObject
{
    public int MsfId { get; set; }
    public List<string> PgId { get; set; }
    public List<string> DcId { get; set; }
}

// for example:
public class Example
{
    public Example()
    {
        // create a list that contains the items.
        var list = new List<SampleObjectSource>
        {
            new SampleObjectSource { MsfId= 100, PgId=  "abc", DcId= "123" },
            new SampleObjectSource { MsfId= 100, PgId=  "def", DcId= "456" },
            new SampleObjectSource { MsfId= 100, PgId=  "ghi", DcId= "789" },
            new SampleObjectSource { MsfId= 101, PgId=  "abc", DcId= "123" },
        };

        // the linq query that does the grouping.
        var query = from item in list
                    // group the items by MsfId
                    group item by item.MsfId into itemgroup
                    // create the new class and initialize the properties
                    select new SampleObject
                    {
                        // the grouping item is the .Key (in this case MsfId)
                        MsfId = itemgroup.Key,
                        // the itemgroup is a collection of all grouped items, so you need to select the properties you're interrested in.
                        DcId = itemgroup.Select(i => i.DcId).ToList(),
                        PgId = itemgroup.Select(i => i.PgId).ToList()
                    };

        // show the results in the Output window.
        foreach (var item in query)
        {
            Trace.WriteLine($"MsfId: {item.MsfId}");
            // some trick to format a list of strings to one string
            Trace.WriteLine($"PgId: {string.Join(", ", item.PgId.Select(s => Quote(s)))}");
            Trace.WriteLine($"DcId: {string.Join(", ", item.DcId.Select(s => Quote(s)))}");
            Trace.WriteLine("");
        }
    }

    // this method will surround the passed string with quotes.
    private string Quote(string item)
    {
        return "\"" + item + "\"";
    }
}

结果:

MsfId: 100
PgId: "abc", "def", "ghi"
DcId: "123", "456", "789"

MsfId: 101
PgId: "abc"
DcId: "123"

答案 3 :(得分:2)

使用适当的重载,使用一个GroupBy完成所有操作。 Working Fiddle Here.

请注意使用SelectMany将分组的集合连接成一个。

var result = sampleObjects
    .GroupBy(
        o => o.MsfId,
        (k, g) => new SampleObject
            {
                MsfId = k,
                PgId = g.SelectMany(p => p.PgId).ToList(),
                DcId = g.SelectMany(p => p.DcId).ToList()
            });

如果要从集合中删除重复项,请考虑Distinct(),例如

var result = sampleObjects
    .GroupBy(
        o => o.MsfId,
        (k, g) => new SampleObject
            {
                MsfId = k,
                PgId = g.SelectMany(p => p.PgId).Distinct().ToList(),
                DcId = g.SelectMany(p => p.DcId).Distinct().ToList()
            });