Основанное на правилах Объединение списка <A>элементов в список <B>в C# - PullRequest
1 голос
/ 01 февраля 2020

У меня есть список. Основываясь на некоторых свойствах объекта типа A, я хочу объединить один или несколько объектов типа A из списка и сформировать новый объект типа B. Объединение будет основано на некоторых предопределенных правилах.

что-то вроде autopper, но input - это список объектов.

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
}

для всех элементов списка, имеющих одинаковые ссылки, я хочу объединить на основе правил, таких как

, если источник имеет значения in (source1, source2, source3)

, затем B.text = a1.text1 + a2.text1 + a3.text1

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

, но если источник имеет значение в (source4)

, тогда это простое сопоставление значений.

Это простой и эффективный способ настройки такого рода правила слияния.

Заранее спасибо.

скажем, List имеет 100 элементов, с 30 различными значениями ref, а для достижимых значений ref существует более одного исходного значения. итоговое количество элементов в List будет меньше 100.

1 Ответ

0 голосов
/ 02 февраля 2020

Вы можете использовать GroupBy для нескольких столбцов (ref и source в данном случае) в запросе LINQ для выполнения желаемого преобразования. Самое сложное - использовать условную группировку во 2-м столбце.

Поскольку у вас есть специальный source(e.g. source4), для которого группировка не нужна. Следовательно, можно добавить фиктивный столбец для GroupBy, который будет иметь фиксированное значение, если source не source4, а new unique (new Guid()), если 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();

Классы и примеры данных, использованные выше code-snippet:

// 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
...