Exemple #1
0
        /// <inheritdoc />
        public override ITreeNode <T> Union(ITreeNode <T> other, DEquality <ITreeNode <T> > equality, DMerge <T> merge)
        {
            // if not equal, return null
            if (!equality(this, other))
            {
                return(null);
            }

            // since values are equal, if they both have no children, return node with value
            if (ChildCount == 0 && other.ChildCount == 0)
            {
                return(new UniqueChildrenTreeNode <T>(merge(Value, other.Value)));
            }

            // return copy of node with children if only 1 has children
            if (ChildCount > 0 && other.ChildCount == 0)
            {
                return(Copy());
            }

            if (other.ChildCount > 0 && ChildCount == 0)
            {
                return(other.Copy());
            }

            // set up the union tree for recursive calculation
            UniqueChildrenTreeNode <T> unionTree = new UniqueChildrenTreeNode <T>(merge(Value, other.Value));

            // sort out children in both that have no equivalent in other
            // perform a union on any nodes that match
            List <ITreeNode <T> > otherNodesNotInOriginal = new List <ITreeNode <T> >(other.Children);
            List <ITreeNode <T> > originalNodesNotInOther = new List <ITreeNode <T> >();

            foreach (ITreeNode <T> child in Children)
            {
                ITreeNode <T> matchingOtherNode = otherNodesNotInOriginal.Find(n => equality(n, child));

                if (matchingOtherNode == default(ITreeNode <T>))
                {
                    originalNodesNotInOther.Add(child);
                }
                else
                {
                    UniqueChildrenTreeNode <T> newUnion
                        = child.Union(matchingOtherNode) as UniqueChildrenTreeNode <T>;

                    if (newUnion == null)
                    {
                        continue;
                    }

                    // add union of matching nodes to tree
                    UnsafeAddChild(unionTree, newUnion);
                    otherNodesNotInOriginal.Remove(matchingOtherNode);
                }
            }

            // copy other nodes missing from original
            foreach (ITreeNode <T> node in otherNodesNotInOriginal)
            {
                node.Copy(unionTree);
            }

            // copy original nodes missing from other
            foreach (ITreeNode <T> node in originalNodesNotInOther)
            {
                node.Copy(unionTree);
            }

            return(unionTree);
        }