gpt4 book ai didi

c# - 在 C# 中合并两个相似的动态对象,在途中创建集合

转载 作者:行者123 更新时间:2023-12-02 05:33:57 26 4
gpt4 key购买 nike

我有多个动态对象(大部分时间)只有几个值不同。我希望能够将这些对象合并为一个对象,如果发生冲突(两个值不相同),我希望将它们存储在一个集合或另一个动态对象中(如果可能)。

我正在使用 expandoObject 类,因此我可以将我的对象转换成字典并尝试合并它,但我还没有找到任何关于合并创建有冲突集合的字典的文章或资源。

是否有一种易于实现且高效的方式来做到这一点?

我将发布一些代码示例,让您对我要完成的工作有一个小小的了解

//returns a dynamic object from JSON (output from DataBase)
JsonReader reader = new JsonReader();
dynamic object = reader.Read(input);

//Creates a dictionairy with all the fieldnames and values.
IDictionary<string, dynamic> properties = (IDictionary<string, dynamic>)object;

//My goal is to merge multiple of these objects into one single object and
//creating collections when values are different from each other.

最佳答案

您的问题似乎是基于 IDictionary<> 接口(interface)。它假定每个键只有一个值。我相信您宁愿转向 LINQ-ish IEnumerable<IGrouping<TKey,TValue>>表示键值集合列表。

当您执行 .GroupBy 或 .ToLookup 调用时,LINQ 会发出此类对象。
那我们玩吧:

using System.Linq;

Dictionary<string, dynamic> A = ...;
Dictionary<string, dynamic> B = ...;

// naiive atempt:
var lookup =
A.Keys.Concat(B.Keys)
.ToDictionary(key => key, key => new dynamic[]{ A[key], B[key] } ));

当然不行,但我写了它,看看它会暴露出什么问题。首先 - 你可能会在连接时得到重复的键。那么并不是所有的键都在 A 和 B 中,所以索引器会抛出错误。接下来,我碰巧假设原始对象是字符串对一个值,并且您可能会处理已经发生碰撞的对象。然后,这仅使用 2 个 A/B 对象,而您可能想要处理多个......

IEnumerable<Dictionary<string, dynamic>> inputs = ....;

// btw. GropuBy returns a lookup, too :) a key -> all matches
var matched_by_keys = inputs.GroupBy(pair => pair.Key);

var final = matched_by_keys.ToDictionary(group => group.Key, group => group);

看那里。我已经拿走了所有的词典,并根据它们的键“将它们配对”。结果,我得到了一个查找,将每个现有键绑定(bind)到先前分配给该键的一系列值。结果 matched_by_keys是一个Enumerable,不是字典,所以后来翻译成了它。查看 ToDictionary 的参数:Group 本身是一个 IEnumerable,只需指出一个键,并且该组不变。

不过,输入仅适用于单值 IDictionary。如果您也需要对多值输入执行此类操作,您可以轻松地将 IDictionaries 转换为查找并对它们执行操作:

IEnumerable<Dictionary<string, dynamic>> inputs1 = ....; // normal items
IEnumerable<ILookup<string, dynamic>> inputs2 = ....; // items that previously already collided

var allAsLookups =
inputs1.ToLookup(pair => pair.Key, pair => pair.Value)
.Concat( inputs2 );

// btw. GropuBy returns a lookup, too :) a key -> all matches
var matched_by_keys = lookups.GroupBy(lk => lk.Key);

var final1 = matched_by_keys.ToDictionary(group => group.Key, group => group.SelectMany(s=>s));

请注意现在必须如何翻译最后的组。在此示例中,groups 不是 IEnumerable<Value> ,但是 IEnumerable<IEnumerable<Value>>因为输入允许是多值的,即使它们只有 1 个值。所以,它必须被展平,这是由 SelectMany 完成的。这反过来不需要投影任何东西,因为该项目已经是 IEnumerable,所以 s=>s 就足够了。

使用 GroupBy、ToLookup 和 ToDictionary 的不同重载,您可以实现许多有用的效果。玩转重载!

关于c# - 在 C# 中合并两个相似的动态对象,在途中创建集合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11968514/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com