c# - 合并两个集合,按属性递归组合重复项

标签 c# recursion collections merge

给定两个具有递归结构的对象集合:

Collection1 = [
    {
        Header: "H1",
        Items: [{
            Header: "H1.1"
        },{
            Header: "H1.2"
        }]
    },
    {
        Header: "H2",
        Items: [{
            Header: "H2.1"
        }]
    }
]

Collection2 = [
    {
        Header: "H1",
        Items: [{
            Header: "H1.1",
            Items: [{
                Header: "H1.1.1"
            }]
        }]
    }
]

我想创建某种函数来组合这两个集合,并将其作为我指示的比较属性(在本例中为 Header),并组合它们的属性,以便结果为大致如下:

Result = [
    {
        Header: "H1",
        Items: [{
            Header: "H1.1",
            Items: [{
                Header: "H1.1.1"
            }]
        },{
            Header: "H1.2"
        }]
    },
    {
        Header: "H2",
        Items: [{
            Header: "H2.1"
        }]
    }
]

正如您所看到的,它会递归地检查对象属性,如果存在类似的项目(在本例中,比较 Header 属性),它只会合并两个对象。

我尝试过Union()Distinct()等,但我似乎找不到实现此目的的方法。

编辑:合并应该在“相同级别”的基础上完成,因此只有在相同深度级别具有相同标题的项目才应被视为相等。

最佳答案

您可以执行以下操作...

假设您有一个与此类似的类:

public class Node {
    public string Header { get; set; }
    public IEnumerable<Node> Items { get; set; }

    public Node() {
        /* Note that I like to start the collections within the object's construction, 
         * to avoid issues inside operations that manipulate these collections. */
        Items = new Collection<Node>();
    }
}

您可以利用 Linq 的优点 Union ,使用 IEqualityComparer 的递归实现。类似这样的事情:

public class NodeComparer : IEqualityComparer<Node>
{
    public bool Equals(Node me, Node another) 
    {
        if (me.Header == another.Header) 
        {
            me.Items = me.Items.Union(another.Items, new NodeComparer()).ToList();

            return true;
        }

        return false;
    }

    public int GetHashCode(Node node) 
    {
        return node.Header.GetHashCode();
    }
}

这个的主要调用是:

var result = collection1.Union(collection2, new NodeComparer()).ToList();

基本上,它的作用是使用 Union 方法进行比较,考虑节点的 header (通过方法 GetHashCode),并且对于具有相同 header 值的每个节点,执行相同的过程为您的 child (通过等于方法),并且这会连续发生在所有级别。

我已经在几个场景中测试了这个解决方案,看起来效果很好,但如果仍然存在某些情况无法解决,也许这是一个很好的开始方式。

关于c# - 合并两个集合,按属性递归组合重复项,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52741707/

相关文章:

c# - yield 递延迭代问题

python - 列表的嵌套级别

java - 为什么java.util中没有设置随机访问

c# - 异步API

c# - Flattern Dictionary<string, HashSet<string>>

c# - 没有 C++ 的 CAD/CAM

java - Project Euler 12,Java解决方案尝试,递归错误?

c# - 无法加载文件或程序集 'System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' 或其依赖项之一

sql - 转换为表格后如何获取 VARRAY 项目的索引

java - Hibernate:集合的集合