【问题标题】:Rule based Merging of list<A> elements into list<B> in C#在 C# 中基于规则将 list<A> 元素合并到 list<B>
【发布时间】:2020-05-17 19:25:09
【问题描述】:

我有一个清单。基于A类型对象的一些属性,我想从列表中合并一个或多个A类型对象并形成一个新的B类型对象。 合并将基于一些预定义的规则。

类似于自动映射器,但输入是对象列表。

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
}

对于列表中具有相同 ref 的所有元素,我想根据诸如

之类的规则进行合并

如果源在 (source1, source2, source3) 中有值

然后 B.text = a1.text1 +a2.text1 +a3.text1

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

但如果源在 (source4) 中有值

那么它就是一个简单的值映射。

这是一种配置这种合并规则的简单有效的方法。

提前致谢。

假设 List 有 100 个元素,具有 30 个不同的参考值,对于到达参考值,源值不止一个。因此 List 中元素的最终计数将小于 100。

【问题讨论】:

  • B.textliststring。你想通过B.text = a1.text1 +a2.text1 +a3.text1实现什么目标?
  • 研究 AutoMapper.Collection.
  • @MKR ,实际上我有两种情况。

标签: c# list linq automapper valueinjecter


【解决方案1】:

您可以在 LINQ 查询中对多列(在本例中为 refsource)使用 GroupBy 来执行所需的转换。棘手的部分是在第二列使用条件分组。

因为你有一个特殊的source(e.g. source4) 不需要分组。因此,可以添加一个用于GroupBy 的虚拟列,如果source 不是source4,但如果它的source4new unique (new Guid()),它将具有固定值。

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-12-09
    • 1970-01-01
    • 2016-09-16
    • 2019-10-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-29
    相关资源
    最近更新 更多