user13755987
user13755987

Reputation:

How to create a new list from property values when grouping items with GroupBy?

I'm using the Newtonsoft package for JSON serialization and currently have this sample code

public class MyObject
{
    public string FirstPathSegment { get; set; }
    public string SecondPathSegment { get; set; }
    public string Value { get; set; }
}

public void Foo()
{
    var collection = new MyObject[] 
    {
        new MyObject() 
        {
            FirstPathSegment = "a",
            SecondPathSegment = "b",
            Value = "the value"
        },
        new MyObject()
        {
            FirstPathSegment = "a",
            SecondPathSegment = "b",
            Value = "another value"
        },
        new MyObject()
        {
            FirstPathSegment = "a",
            SecondPathSegment = "z",
            Value = "the value"
        }
    };
    
    var result = JsonConvert.SerializeObject(collection);
    
    Console.WriteLine(result);
}

I want to group all those items, the key is the combination of FirstPathSegment and SecondPathSegment. The problem is that Value should be an array containing all the values from the grouped elements. First I tried to use GroupBy this way

    var foo = collection.GroupBy(
        myObject => myObject.FirstPathSegment + myObject.SecondPathSegment,
        myObject => myObject.Value
    );

The actual serialized output of foo is

[["the value","another value"],["the value"]]

The desired output at the end should be

[
  {
    "FirstPathSegment": "a",
    "SecondPathSegment": "b",
    "Values": [
      "the value",
      "another value"
    ]
  },
  {
    "FirstPathSegment": "a",
    "SecondPathSegment": "z",
    "Values": [
      "the value"
    ]
  }
]

If that's not possible because the keys get merged it would also be fine to have this

[
  {
    "Key": "ab",
    "Values": [
      "the value",
      "another value"
    ]
  },
  {
    "Key": "az",
    "Values": [
      "the value"
    ]
  }
]

Does someone know how to achieve that?

Upvotes: 2

Views: 469

Answers (1)

user1672994
user1672994

Reputation: 10849

Group by using below statement where grouped key is defined as composite key.

var grouped = collection.GroupBy(
                g => new { g.FirstPathSegment, g.SecondPathSegment })
               .Select(g => new 
                              { 
                                   FirstPathSegment = g.Key.FirstPathSegment, 
                                   SecondPathSegment = g.Key.SecondPathSegment, 
                                   Value = g.Select(h => h.Value) 
                              }
                 );

Above will do the grouping what you require.

Check this fiddle -- https://dotnetfiddle.net/xqMf2d

The output of above code is

[
    {
        "FirstPathSegment": "a",
        "SecondPathSegment": "b",
        "Value": [ "the value", "another value" ]
    },
    {
        "FirstPathSegment": "a",
        "SecondPathSegment": "z",
        "Value": [ "the value" ]
    }
]

Upvotes: 3

Related Questions