/// <summary> /// Flatten <paramref name="node"/> to key lines. /// </summary> /// <param name="node"></param> /// <param name="lineAppender">(optional) overriding appender</param> /// <returns></returns> public static IEnumerable <ILine> ToLines(this ILineTree node, ILineFactory lineAppender = default) { Queue <(ILineTree, ILine)> queue = new Queue <(ILineTree, ILine)>(); queue.Enqueue((node, node.Key)); while (queue.Count > 0) { // Next element (ILineTree, ILine)current = queue.Dequeue(); // Yield values if (current.Item2 != null && current.Item1.HasValues) { foreach (ILine value in current.Item1.Values) { yield return(current.Item2.Concat(value)); } } // Enqueue children if (current.Item1.HasChildren) { foreach (ILineTree child in current.Item1.Children) { if (lineAppender != null) { ILine childKey = lineAppender.Concat(lineAppender.Clone(current.Item2), child.Key); queue.Enqueue((child, childKey)); } else { ILine childKey = current.Item2 == null ? child.Key : current.Item2.Concat(child.Key); queue.Enqueue((child, childKey)); } } } } }