合并两个列表和组合对象值

本文关键字:组合 对象 列表 两个 合并 | 更新日期: 2023-09-27 18:17:16

我做了很多挖掘,但我似乎找不到这个特殊问题的答案;类似的问题的答案,但不是这样的。

本质上,我要做的是取两个c#列表,它们都包含一系列由字符串-整数对组成的c#对象,然后将它们合并在一起,将相似对象的值连接在一起。

假设对象类是这样的;

public class Object
{
    public string Name;
    public int Value;
}

我们还会说我的列表是这样的;

    objectList1             objectList2
 Name        Value       Name        Value
Object1        1        Object1        1
Object2        1        Object2        1
Object3        1
Object4        1
Object5        1

我的目标是将objectList2的Objects的内容与objectList1中相应的Objects相结合。在这个例子中,这将意味着objectList1看起来像这样,当所有的说和做;

 Name        Value
Object1        2
Object2        2
Object3        1
Object4        1
Object5        1

现在我知道这是可能的foreachFindIndex()调用,但我几乎肯定有一个更有效的方法去做这件事。如果我错了,没关系,但我想知道我是否可以优化这个,因为我的直觉告诉我,一定有一个更简单的方法。

合并两个列表和组合对象值

我相信你想做的事情:

var contents = sample.Concat(example).GroupBy(n => n.Name);

基本上它将创建一个分组,但它将把列表附加在一起。然后根据名称分组,这将提供一个数字指示符,显示存在多少个相同的名称。基本上,你最终会得到一个IGrouping<Key, Value>

例如:

var merge = new List<Content>();
var contents = sample.Concat(example).GroupBy(n => n.Name);
foreach(var item in contents)
     merge.Add(new Content() { Name = item.Key, Value = item.Sum(value => value.Value) });

如果你想的话,你也可以用所有的Linq来做:

    var contents = example.Concat(sample)
        .GroupBy(n => n.Name)
        .SelectMany(content => 
                    content.Select((item, i) => new { Name = content.Key, Value = content.Sum(v => v.Value) }).Distinct());

我能想到的最好办法是使用Dictionary,假设所有键都是唯一的

对较小的Dictionary(如下所示)执行foreach操作,检查另一个Dictionary中的匹配键,如果找到则修改,如果未找到则添加(注意此算法是破坏性的,如果想保留原件,请复制返回)

    void Merge (Dictionary<string, int> a, Dictionary<string, int> b)
    {
        foreach (string key in a.Keys)
        {
            if (b.ContainsKey(key))
            {
                b[key] = b[key] + a[key];
            }
            else
            {
                b.Add(key, a[key]);
            }
        }
    }

您可以像下面这样使用LINQ

 var list1 = new List<Object>();
list1.Add(new Object { Name = "Object1", Value = 1 });
list1.Add(new Object { Name = "Object2", Value = 1 });
list1.Add(new Object { Name = "Object3", Value = 1 });
list1.Add(new Object { Name = "Object4", Value = 1 });
list1.Add(new Object { Name = "Object5", Value = 1 });
var list2 = new List<Object>();
list2.Add(new Object { Name = "Object1", Value = 1 });
list2.Add(new Object { Name = "Object2", Value = 1 });
var total = from item1 in list1
            join item2 in list2
            on item1.Name equals item2.Name into list3
            from subset in list3.DefaultIfEmpty()
            select new Object
            {
                Name = item1.Name,
                Value = item1.Value + (subset == null ? 0 : subset.Value)
            };