Exemplo n.º 1
0
        /// <inheritdoc />
        protected override async Task <IEnumerable <IDocument> > ExecuteContextAsync(IExecutionContext context)
        {
            // Create a dictionary of tree nodes
            TreeNodeEqualityComparer        treeNodeEqualityComparer = new TreeNodeEqualityComparer();
            Dictionary <string[], TreeNode> nodesDictionary          = await context.Inputs
                                                                       .ToAsyncEnumerable()
                                                                       .SelectAwait(async input => new TreeNode(await _treePath.GetValueAsync(input, context), input))
                                                                       .Where(x => x.TreePath != null)
                                                                       .Distinct(treeNodeEqualityComparer)
                                                                       .ToDictionaryAsync(x => x.TreePath, new TreePathEqualityComparer());

            // Add links between parent and children (creating empty tree nodes as needed)
            Queue <TreeNode> nodesToProcess = new Queue <TreeNode>(nodesDictionary.Values);

            while (nodesToProcess.Count > 0)
            {
                TreeNode node = nodesToProcess.Dequeue();

                // Skip root nodes
                if (node.TreePath.Length == 0 ||
                    (node.InputDocument != null && await _isRoot.GetValueAsync(node.InputDocument, context)))
                {
                    continue;
                }

                // Skip the root node if not nesting or if collapsing the root
                string[] parentTreePath = node.GetParentTreePath();
                if (parentTreePath.Length == 0 && (!_nesting || _collapseRoot))
                {
                    continue;
                }

                // Find (or create) the parent
                if (!nodesDictionary.TryGetValue(parentTreePath, out TreeNode parent))
                {
                    parent = new TreeNode(parentTreePath);
                    nodesDictionary.Add(parentTreePath, parent);
                    nodesToProcess.Enqueue(parent);
                }

                // Add the parent and child relationship
                node.Parent = parent;
                parent.Children.Add(node);
            }

            // Recursively generate child output documents
            foreach (TreeNode node in nodesDictionary.Values.Where(x => x.Parent == null))
            {
                await node.GenerateOutputDocumentsAsync(this, context);
            }

            // Return parent nodes or all nodes depending on nesting
            return(nodesDictionary.Values
                   .Where(x => (!_nesting || x.Parent == null) && x.OutputDocument != null)
                   .Select(x => x.OutputDocument));
        }
Exemplo n.º 2
0
        /// <inheritdoc />
        public IEnumerable <IDocument> Execute(IReadOnlyList <IDocument> inputs, IExecutionContext context)
        {
            // Create a dictionary of tree nodes
            TreeNodeEqualityComparer        treeNodeEqualityComparer = new TreeNodeEqualityComparer();
            Dictionary <object[], TreeNode> nodes = inputs
                                                    .Select(x => new TreeNode(this, x, context))
                                                    .Where(x => x.TreePath != null)
                                                    .Distinct(treeNodeEqualityComparer)
                                                    .ToDictionary(x => x.TreePath, new TreePathEqualityComparer());

            // Add links between parent and children (creating empty tree nodes as needed)
            Queue <TreeNode> nodesToProcess = new Queue <TreeNode>(nodes.Values);

            while (nodesToProcess.Count > 0)
            {
                TreeNode node = nodesToProcess.Dequeue();

                // Skip root nodes
                if (node.TreePath.Length == 0 ||
                    (node.InputDocument != null && _isRoot.Invoke <bool>(node.InputDocument, context)))
                {
                    continue;
                }

                // Skip the root node if not nesting or if collapsing the root
                object[] parentTreePath = node.GetParentTreePath();
                if (parentTreePath.Length == 0 && (!_nesting || _collapseRoot))
                {
                    continue;
                }

                // Find (or create) the parent
                TreeNode parent;
                if (!nodes.TryGetValue(parentTreePath, out parent))
                {
                    parent = new TreeNode(parentTreePath);
                    nodes.Add(parentTreePath, parent);
                    nodesToProcess.Enqueue(parent);
                }

                // Add the parent and child relationship
                node.Parent = parent;
                parent.Children.Add(node);
            }

            // Recursively generate child output documents
            foreach (TreeNode node in nodes.Values.Where(x => x.Parent == null))
            {
                node.GenerateOutputDocuments(this, context);
            }

            // Return parent nodes or all nodes depending on nesting
            return(nodes.Values
                   .Where(x => (!_nesting || x.Parent == null) && x.OutputDocument != null)
                   .Select(x => x.OutputDocument));
        }