c# - 如何在 C# 中将两个 List<dynamic> 对象合并为一个具有特定条件的对象?

标签 c# dynamic merge

列出对象1

[ { "empId":10001, "empName":"test1" }, { "empId":10002, "empName":"test2" } ]

列出对象2

[ { "empId":10001, "emailAddress":"<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="473322343376072a262e2b6924282a" rel="noreferrer noopener nofollow">[email protected]</a>" }, { "empId":10002, "emailAddress":"<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="81f5e4f2f5b3c1ece0e8edafe2eeec" rel="noreferrer noopener nofollow">[email protected]</a>" } ]


Trying to get the merge result which matches "empId" in both objects.

结果

[
   {
      "empId":10001,
      "empName":"test1",
      "emailAddress":"<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="592d3c2a2d681934383035773a3634" rel="noreferrer noopener nofollow">[email protected]</a>"
   },
   {
      "empId":10002,
      "empName":"test2",
      "emailAddress":"<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="285c4d5b5c1a6845494144064b4745" rel="noreferrer noopener nofollow">[email protected]</a>"
   }
]

我已经尝试过https://www.newtonsoft.com/json/help/html/MergeJson.htm 。但无法执行匹配逻辑“empId”

最佳答案

这里是一些将加入和合并的代码,working here .

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Dynamic;
using System.Linq;

using Newtonsoft.Json;
                    
public class Program
{
    public static void Main()
    {
        var list1 = new[]
            { 
                new { empId = 10001, empName = "test1" },
                new { empId = 10002, empName = "test2" }
            };
        
        var list2 = new[]
            {
                new { empId = 10001, emailAddress = "<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="fb8f9e888fcabb969a9297d5989496" rel="noreferrer noopener nofollow">[email protected]</a>" },
                new { empId = 10002, emailAddress = "<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="6f1b0a1c1b5d2f020e0603410c0002" rel="noreferrer noopener nofollow">[email protected]</a>" }
            };
        
        var results1 = list1.MergeJoin(list2, e => e.empId);
        
        Console.WriteLine($"{nameof(results1)}:");
        Console.WriteLine(JsonConvert.SerializeObject(results1, Formatting.Indented));
        Console.WriteLine();
        
        IList<dynamic> dynamicList1 = new List<dynamic>
        { 
            new { empId = 10001, empName = "test1", utterance = "wibble" },
            new { empId = 10002, empName = "test2", expression = "bemused" }
        };
        
        IList<dynamic> dynamicList2 = new List<dynamic>
        {
            new { empId = 10001, emailAddress = "<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="95e1f0e6e1a4d5f8f4fcf9bbf6faf8" rel="noreferrer noopener nofollow">[email protected]</a>", IQ = "moron" },
            new { empId = 10002, emailAddress = "<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="b9cddccacd8bf9d4d8d0d597dad6d4" rel="noreferrer noopener nofollow">[email protected]</a>", smell = "cheesy" }
        };
        
        var results2 = dynamicList1.MergeJoin(dynamicList2, e => e.empId);
        
        Console.WriteLine($"{nameof(results2)}:");
        Console.WriteLine(JsonConvert.SerializeObject(results2, Formatting.Indented));
    }
}

public static class Extensions
{
    public static IEnumerable<dynamic> MergeJoin<TKey>(
        this IEnumerable<dynamic> outer,
        IEnumerable<dynamic> inner,
        Func<dynamic, TKey> keyAccessor)
    {
        return outer.Join(
            inner,
            keyAccessor,
            keyAccessor,
            Merge);
    }
    
    public static dynamic Merge(dynamic left, dynamic right)
    {
        IDictionary<string, object> dictionary1 = GetKeyValueMap(left);
        IDictionary<string, object> dictionary2 = GetKeyValueMap(right);

        var result = new ExpandoObject();

        var d = result as IDictionary<string, object>;
        foreach (var pair in dictionary1.Concat(dictionary2))
        {
            d[pair.Key] = pair.Value;
        }

        return result;
    }

    private static IDictionary<string, object> GetKeyValueMap(object values)
    {
        if (values == null)
        {
            return new Dictionary<string, object>();
        }

        var map = values as IDictionary<string, object>;
        if (map != null)
        {
            return map;
        }

        map = new Dictionary<string, object>();
        foreach (PropertyDescriptor descriptor in TypeDescriptor.GetProperties(values))
        {
            map.Add(descriptor.Name, descriptor.GetValue(values));
        }

        return map;
    }
}

这应该输出,

results1:
[
  {
    "empId": 10001,
    "empName": "test1",
    "emailAddress": "<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="6e1a0b1d1a5f2e030f0702400d0103" rel="noreferrer noopener nofollow">[email protected]</a>"
  },
  {
    "empId": 10002,
    "empName": "test2",
    "emailAddress": "<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="1f6b7a6c6b2d5f727e7673317c7072" rel="noreferrer noopener nofollow">[email protected]</a>"
  }
]

results2:
[
  {
    "empId": 10001,
    "empName": "test1",
    "utterance": "wibble",
    "emailAddress": "<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="c6b2a3b5b2f786aba7afaae8a5a9ab" rel="noreferrer noopener nofollow">[email protected]</a>",
    "IQ": "moron"
  },
  {
    "empId": 10002,
    "empName": "test2",
    "expression": "bemused",
    "emailAddress": "<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="9febfaecebaddff2fef6f3b1fcf0f2" rel="noreferrer noopener nofollow">[email protected]</a>",
    "smell": "cheesy"
  }
]

关于c# - 如何在 C# 中将两个 List<dynamic> 对象合并为一个具有特定条件的对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/74550257/

相关文章:

c# - 如何在 Windows Mobile 6 中模拟存储卡?

c# - 使用 VS2012 附带的 Install Shield 创建可更新的设置

c# - 将克罗地亚语日期字符串解析为 DateTime

C++动态整数数组有时会导致崩溃

javascript - 在 JavaScript 中如何将两个对象合并到同一个属性中?

svn - 如果我不从 Subversion 中的主干合并,是否需要重新集成?

c# - 在代码中将凭据(用户名/密码)分配给 EF

java - ASM 动态子类创建 - NoClassDefFoundError BeanInfo

arrays - 创建具有可变数量元素的数组变量

ms-access - 在 MS Access 中合并类似日期