Home > database >  How to restructure an Object in C# using LINQ?
How to restructure an Object in C# using LINQ?

Time:02-26

I have a data set as follows:

[
    {
        "Id": 1,
        "Country": "Uruguay",
        "Name": "Foo",
        "Status": "Completed",
    },
    {
        "Id": 2,
        "Country": "Uruguay",
        "Name": "Foo",
        "Status": "Completed",
    },
    {
        "Id": 3,
        "Country": "Germany",
        "Name": "Foo",
        "Status": "Completed",
    },
]

I want to transform and sort it by Country so that it looks as follows:

[
    {
        "Country": "Uruguay",
        "Details": [
         {
            "Id": 1,
            "Name": "Foo",
            "Status": "Completed",
         },
         {
            "Id": 2,
            "Name": "Foo",
            "Status": "Completed",
         },
        ],
    },
    {
        "Country": "Germany",
        "Details": [
         {
            "Id": 3,
            "Name": "Foo",
            "Status": "Completed",
         },
        ],
    },
],

These are the classes in C#:

public class Countries {
    public int Id { get; set; }
    public string Country { get; set; }
    public string Name { get; set; }
    public string Status { get; set; }
}

public class Details {
    public int Id { get; set; }
    public string Name { get; set; }
    public string Status { get; set; }
}

public class CountryList {
    public string Country { get; set; }
    public List<Details> Details { get; set; }
}

Some of what I have tried looks as followed:

var foo = countries
    .GroupBy(x => new Details { Id = x.Id, Name = x.Name, Status = x.Status })
    .Select( y => new CountryList 
     {
         // Country = y.Key. 
     }

var foo = countries
    .GroupBy(x => x.Country)
    .Select( y => new CountryList 
     {
         // Country = y.Key.
         Details = y.GroupBy(a => new Details 
         { 
            Id = a.Id, 
            Name = a.Name, 
            Status = a.Status  
         }).ToList() 
     }

I am having trouble working out how to use LINQ to solve this. I have done a handful of GroupBy operations in the past, but I wasn't able to work this one out. How do I transform my dataset into the desired result?

CodePudding user response:

You do not need second GroupBy

var foo = countries
    .GroupBy(x => x.Country)
    .Select(y => new CountryList 
     {
         Country = y.Key,
         Details = y.Select(a => new Details 
         { 
            Id = a.Id, 
            Name = a.Name, 
            Status = a.Status  
         }).ToList() 
     };

CodePudding user response:

You can take advantage of the .GroupBy() overload that lets you define a resultSelector to create your CountryLists and populate their Details:

var countries = new List<Countries>
{
    new() { Id = 1, Country = "Uruguay", Name = "Foo", Status = "Completed" },
    new() { Id = 2, Country = "Uruguay", Name = "Foo", Status = "Completed" },
    new() { Id = 3, Country = "Germany", Name = "Foo", Status = "Completed" },
};

List<CountryList> countryList = countries
    .GroupBy(
        c => c.Country,
        ( country, matches ) => new CountryList()
            {
                Country = country,
                Details = matches.Select(match => new Details 
                    { 
                        Id = match.Id, 
                        Name = match.Name, 
                        Status = match.Status 
                    }).ToList()
            })
    .ToList();

, ( country, matches ) => new CountryList() { ... } being the resultSelector.


Example fiddle here.

CodePudding user response:

try this

var orig = JsonConvert.DeserializeObject<List<Countries>>(json); 

List<CountryList> countries = orig.GroupBy(o => o.Country)
.Select(x => new CountryList {
Country = x.Key,
Details = x.Select(o => new Details {Id=o.Id,Name=o.Name,Status=o.Status} ).ToList()
}).ToList();

 
  • Related