1

I have a list. Based on some properties of object of type A, I want to merge one or more object of type A from the list and form a new object of type B. Merging will be based on some predefined rules.

something like automapper, but input is a list of object.

Example 
class A {
 Guid source;
 int ref;
 string text1;
 string text2;
 int Value
}
class B {
 List<Guid> source;
 int ref;
 List<string> text;
 int Value
}

for all the elements of a list which has the same ref, I want to merge based on rules like

if source has values in (source1, source2, source3)

then B.text = a1.text1 +a2.text1 +a3.text1

and b.Value = a1.Value +a2.Value +a3.Value

but if source has value in (source4)

then it is a simple mapping of values.

This there a simple and efficient way of configuring this kind of merging rules.

Thanks in advance.

let say List has 100 elements, with 30 different ref values and for reach ref values there are more than one source values. so the final count of elements in List will be less than 100.

Ramveer Singh
  • 39
  • 1
  • 5

1 Answers1

0

You can use GroupBy on multi-column (ref and source in this case) in LINQ query to perform desired transformation. The tricky part is use a conditional grouping on 2nd column.

Since you have a special source(e.g. source4) for which grouping is not desired. Hence, a dummy column for GroupBy can be added that will have fixed value if source is not source4 but a new unique (new Guid()) if its source4.

// source4 : No grouping needed on this
var guidUngroup = new Guid("aed48532-0a92-4093-bbb1-19afe64cef15");
var bObjects = aObjects
                .GroupBy(a => new
                {
                    a.refVal,
                    dummySource = a.source == guidUngroup ?Guid.NewGuid():guidUngroup
                })
                .Select(g => new B
                 {
                     source = g.Select(a => a.source).ToList<Guid>(),
                     refVal = g.Key.refVal,
                     text = g.Select(a => a.text1).ToList<string>(),
                     Value = g.Sum(a => a.Value)
                 })
                 .ToList();

The classes and sample data used in above code-snippet are:

// Sample data and result.
public class A
{
    public Guid source { get; set; }
    public int refVal { get; set; }   //Name changed from original post
    public string text1 { get; set; }
    public string text2 { get; set; }
    public int Value { get; set; }
}
public class B
{
    public List<Guid> source { get; set; }
    public int refVal { get; set; }     //Name changed from original post
    public List<string> text { get; set; }
    public int Value { get; set; }
}

var aObjects = new List<A>{new A(){source = new Guid("c3a52882-069a-4fe5-b37f-0ffe00b3299c"),
              refVal = 100,
              text1 = "1text1",
              text2 = "1text2",
              Value = 10 },
              new A(){source = new Guid("bcf4cbbf-e01f-48fb-9a45-cc4d9bd5647d"),
              refVal = 100,
              text1 = "2text1",
              text2 = "2text2",
              Value = 20 },
              new A(){source = new Guid("9f50a0af-3507-4a2b-be25-842f01372194"),
              refVal = 100,
              text1 = "3text1",
              text2 = "3text2",
              Value = 30 },
              new A(){source = new Guid("aed48532-0a92-4093-bbb1-19afe64cef15"),
              refVal = 101,
              text1 = "4text1",
              text2 = "4text2",
              Value = 40 },
              new A(){source = new Guid("aed48532-0a92-4093-bbb1-19afe64cef15"),
              refVal = 101,
              text1 = "5text1",
              text2 = "5text2",
              Value = 50 }};



//Result : list of B objects stored in aObjects 
Source : c3a52882-069a-4fe5-b37f-0ffe00b3299c,bcf4cbbf-e01f-48fb-9a45-cc4d9bd5647d,9f50a0af-3507-4a2b-be25-842f01372194
refVal : 100
Source : 1text1,2text1,3text1
Value : 60

Source : aed48532-0a92-4093-bbb1-19afe64cef15
refVal : 101
Source : 4text1
Value : 40

Source : aed48532-0a92-4093-bbb1-19afe64cef15
refVal : 101
Source : 5text1
Value : 50
MKR
  • 19,739
  • 4
  • 23
  • 33