j0w
j0w

Reputation: 545

Using linQ to group list of object into new lists of objects

So I am trying to group a list of ErrorItem into a list of ValidationFormatErrorDTO, depending on either the FieldType or the ValidationFormat.

The goal is to have a list of ValidationFormatErrorDTO containing only one type of errors.

The final object. So I am trying to have a list of it:

  public class ValidationFormatErrorDTO
    {
       public ValidationFormat ValidationFormat { get; set; }
       public FieldType FieldType { get; set; }
       public List<ValidationFormatErrorItemDTO> ErrorItems { get; set; }
    }


   public class ValidationFormatErrorItemDTO
    {
        public int LineNumber { get; set; }
        public string LineValue { get; set; }
    }

Examples of error objects:

example 1:

 var error = new ErrorItem
 {
  LineNumber = 2,
  LineValue = "Test",
  FieldType = FieldType.DateTime,
  ValidationFormat = null
 };

example 2:

   error = new ErrorItem
   {
     LineNumber = 11,
     LineValue = "john.doe.test.com",
     ValidationFormat = ValidationFormat.Email,
     FieldType = null
    };

example 3:

   error = new ErrorItem
   {
     LineNumber = 32,
     LineValue = "1212",
     ValidationFormat = ValidationFormat.PhoneNumber,
     FieldType = null
    };

And from here I'm stuck.

I've tried this:

var test = tempListErrors.GroupBy(x => x.ValidationFormat)
                    .Select(y => new ValidationFormatErrorDTO
                    {
                        ValidationFormat = y.Key,
                        ErrorItems = ??
                    }).ToList();

But first of all it means I should do the same for errors based on the FieldType. Which would give me 2 lists of ValidationFormatErrorDTO I would the have to join into 1 list.

And second, with this method I'm stuck with an IGrouping<ValidationFormat, ErrorItem> I don't know how to deal with.

I any of you think about how to do it with from where I am right now, or think about a better solution, that would be awesome!

Thanks for your time!

EDITS:

So, according to @Ashkan's answer, I would have this:

var formatErrors = tempListErrors.GroupBy(x => x.ValidationFormat)
                    .Select(y => new ValidationFormatErrorDTO
                    {
                        ValidationFormat = y.Key,
                        ErrorItems = y.Select(x => new ValidationFormatErrorItemDTO
                        {
                            LineNumber = x.LineNumber,
                            LineValue = x.LineValue
                        }).ToList()
                    }).ToList();

                var fieldTypeErrors = tempListErrors.GroupBy(x => x.FieldType)
                    .Select(y => new ValidationFormatErrorDTO
                    {
                        FieldType = y.Key,
                        ErrorItems = y.Select(x => new ValidationFormatErrorItemDTO
                        {
                            LineNumber = x.LineNumber,
                            LineValue = x.LineValue
                        }).ToList()
                    }).ToList();

Any idea on how I can now merge those two? Or how to group by both ValidationFormatand FieldType to get only one list? Something like this?

var both = tempListErrors.GroupBy(x => new { x.ValidationFormat, x.FieldType })
                    .Select(y => new ValidationFormatErrorDTO
                    {
                        ValidationFormat = y.Key.ValidationFormat,
                        FieldType = y.Key.FieldType,
                        ErrorItems = y.Select(x => new ValidationFormatErrorItemDTO
                        {
                            LineNumber = x.LineNumber,
                            LineValue = x.LineValue
                        }).ToList()
                    }).ToList();

Upvotes: 0

Views: 143

Answers (2)

Nguyễn Văn Phong
Nguyễn Văn Phong

Reputation: 14198

IGrouping I don't know how to deal with.

According to this specs it means that

Represents a collection of objects that have a common key

So from that point, you can get a list of ErrorItems like this

ErrorItems = group.Select(item => new ValidationFormatErrorItemDTO 
                          {
                              LineNumber = item.LineNumber,
                              LineValue = item.LineValue
                          }).ToList()

Updated

var test = tempListErrors.GroupBy(p => new { p.ValidationFormat, p.FieldType})
                    .Select(group => new ValidationFormatErrorDTO
                    {
                        ValidationFormat = group.Key.ValidationFormat,
                        ErrorItems = group.Select(item => new ValidationFormatErrorItemDTO 
                          {
                              LineNumber = item.LineNumber,
                              LineValue = item.LineValue
                          }).ToList()
                    }).ToList();

Upvotes: 1

Ashkan Mobayen Khiabani
Ashkan Mobayen Khiabani

Reputation: 34152

as y is the each group, so you can perform a .Select() on y to get a List<ValidationFormatErrorItemDTO>:

var test = tempListErrors.GroupBy(x => x.ValidationFormat)
                    .Select(y => new ValidationFormatErrorDTO
                    {
                        ValidationFormat = y.Key,
                        ErrorItems = y.Select(x => new ValidationFormatErrorItemDTO 
                          {
                              LineNumber = x.LineNumber,
                              LineValue = x.LineValue
                          }).ToList()
                    }).ToList();

Upvotes: 1

Related Questions