static <T> Stream<Node<T>> traverseLevelOrder(Node<T> node) { Stream<Node<T>> result = Stream.empty(); final java.util.Queue<Node<T>> queue = new java.util.LinkedList<>(); queue.add(node); while (!queue.isEmpty()) { final Node<T> next = queue.remove(); result = result.prepend(next); queue.addAll(next.getChildren().toJavaList()); } return result.reverse(); }
@Override public boolean equals(Object o) { if (o == this) { return true; } else if (o instanceof Node) { final Node<?> that = (Node<?>) o; return Objects.equals(this.getValue(), that.getValue()) && Objects.equals(this.getChildren(), that.getChildren()); } else { return false; } }
@SuppressWarnings("unchecked") static <T, U, R> Tree<R> zip(Node<T> node, java.util.Iterator<? extends U> that, BiFunction<? super T, ? super U, ? extends R> mapper) { if (!that.hasNext()) { return Empty.instance(); } else { final R value = mapper.apply(node.getValue(), that.next()); final io.vavr.collection.List<Node<R>> children = (io.vavr.collection.List<Node<R>>) (Object) node .getChildren() .map(child -> zip(child, that, mapper)) .filter(Tree::nonEmpty); return new Node<>(value, children); } }
static <T, T1, T2, T3> Tuple3<Node<T1>, Node<T2>, Node<T3>> unzip3(Node<T> node, Function<? super T, Tuple3<? extends T1, ? extends T2, ? extends T3>> unzipper) { final Tuple3<? extends T1, ? extends T2, ? extends T3> value = unzipper.apply(node.getValue()); final io.vavr.collection.List<Tuple3<Node<T1>, Node<T2>, Node<T3>>> children = node.getChildren() .map(child -> unzip3(child, unzipper)); final Node<T1> node1 = new Node<>(value._1, children.map(t -> t._1)); final Node<T2> node2 = new Node<>(value._2, children.map(t -> t._2)); final Node<T3> node3 = new Node<>(value._3, children.map(t -> t._3)); return Tuple.of(node1, node2, node3); }
static <T> Stream<Node<T>> traverseLevelOrder(Node<T> node) { Stream<Node<T>> result = Stream.empty(); final java.util.Queue<Node<T>> queue = new java.util.LinkedList<>(); queue.add(node); while (!queue.isEmpty()) { final Node<T> next = queue.remove(); result = result.prepend(next); queue.addAll(next.getChildren().toJavaList()); } return result.reverse(); }
static <T> Stream<Node<T>> traversePostOrder(Node<T> node) { return node .getChildren() .foldLeft(Stream.<Node<T>> empty(), (acc, child) -> acc.appendAll(traversePostOrder(child))) .append(node); }
static <T> Stream<Node<T>> traversePreOrder(Node<T> node) { return node.getChildren().foldLeft(Stream.of(node), (acc, child) -> acc.appendAll(traversePreOrder(child))); }
@SuppressWarnings("unchecked") static <T, U> Tree<Tuple2<T, U>> zipAll(Node<T> node, java.util.Iterator<? extends U> that, U thatElem) { if (!that.hasNext()) { return node.map(value -> Tuple.of(value, thatElem)); } else { final Tuple2<T, U> value = Tuple.of(node.getValue(), that.next()); final io.vavr.collection.List<Node<Tuple2<T, U>>> children = (io.vavr.collection.List<Node<Tuple2<T, U>>>) (Object) node .getChildren() .map(child -> zipAll(child, that, thatElem)) .filter(Tree::nonEmpty); return new Node<>(value, children); } } }
static <T> Stream<Node<T>> traverseInOrder(Node<T> node) { if (node.isLeaf()) { return Stream.of(node); } else { final io.vavr.collection.List<Node<T>> children = node.getChildren(); return children .tail() .foldLeft(Stream.<Node<T>> empty(), (acc, child) -> acc.appendAll(traverseInOrder(child))) .prepend(node) .prependAll(traverseInOrder(children.head())); } }
static <T, T1, T2> Tuple2<Node<T1>, Node<T2>> unzip(Node<T> node, Function<? super T, Tuple2<? extends T1, ? extends T2>> unzipper) { final Tuple2<? extends T1, ? extends T2> value = unzipper.apply(node.getValue()); final io.vavr.collection.List<Tuple2<Node<T1>, Node<T2>>> children = node .getChildren() .map(child -> unzip(child, unzipper)); final Node<T1> node1 = new Node<>(value._1, children.map(t -> t._1)); final Node<T2> node2 = new Node<>(value._2, children.map(t -> t._2)); return Tuple.of(node1, node2); }
@Override public boolean equals(Object o) { if (o == this) { return true; } else if (o instanceof Node) { final Node<?> that = (Node<?>) o; return Objects.equals(this.getValue(), that.getValue()) && Objects.equals(this.getChildren(), that.getChildren()); } else { return false; } }
@SuppressWarnings("unchecked") static <T, U> Tree<Tuple2<T, U>> zipAll(Node<T> node, java.util.Iterator<? extends U> that, U thatElem) { if (!that.hasNext()) { return node.map(value -> Tuple.of(value, thatElem)); } else { final Tuple2<T, U> value = Tuple.of(node.getValue(), that.next()); final io.vavr.collection.List<Node<Tuple2<T, U>>> children = (io.vavr.collection.List<Node<Tuple2<T, U>>>) (Object) node .getChildren() .map(child -> zipAll(child, that, thatElem)) .filter(Tree::nonEmpty); return new Node<>(value, children); } } }
static <T> Node<T> replace(Node<T> node, T currentElement, T newElement) { if (Objects.equals(node.getValue(), currentElement)) { return new Node<>(newElement, node.getChildren()); } else { for (Node<T> child : node.getChildren()) { final Node<T> newChild = replace(child, currentElement, newElement); final boolean found = newChild != child; if (found) { final io.vavr.collection.List<Node<T>> newChildren = node.getChildren().replace(child, newChild); return new Node<>(node.getValue(), newChildren); } } return node; } }
@SuppressWarnings("unchecked") static <T, U> Tree<U> flatMap(Node<T> node, Function<? super T, ? extends Iterable<? extends U>> mapper) { final Tree<U> mapped = ofAll(mapper.apply(node.getValue())); if (mapped.isEmpty()) { return empty(); } else { final io.vavr.collection.List<Node<U>> children = (io.vavr.collection.List<Node<U>>) (Object) node .getChildren() .map(child -> flatMap(child, mapper)) .filter(Tree::nonEmpty); return of(mapped.get(), children.prependAll(mapped.getChildren())); } }
static <T> Stream<Node<T>> traversePreOrder(Node<T> node) { return node.getChildren().foldLeft(Stream.of(node), (acc, child) -> acc.appendAll(traversePreOrder(child))); }
static <T, T1, T2> Tuple2<Node<T1>, Node<T2>> unzip(Node<T> node, Function<? super T, Tuple2<? extends T1, ? extends T2>> unzipper) { final Tuple2<? extends T1, ? extends T2> value = unzipper.apply(node.getValue()); final io.vavr.collection.List<Tuple2<Node<T1>, Node<T2>>> children = node .getChildren() .map(child -> unzip(child, unzipper)); final Node<T1> node1 = new Node<>(value._1, children.map(t -> t._1)); final Node<T2> node2 = new Node<>(value._2, children.map(t -> t._2)); return Tuple.of(node1, node2); }
static <T> Stream<Node<T>> traversePostOrder(Node<T> node) { return node .getChildren() .foldLeft(Stream.<Node<T>> empty(), (acc, child) -> acc.appendAll(traversePostOrder(child))) .append(node); }
static <T, U> Node<U> map(Node<T> node, Function<? super T, ? extends U> mapper) { final U value = mapper.apply(node.getValue()); final io.vavr.collection.List<Node<U>> children = node.getChildren().map(child -> map(child, mapper)); return new Node<>(value, children); }
static <T, T1, T2, T3> Tuple3<Node<T1>, Node<T2>, Node<T3>> unzip3(Node<T> node, Function<? super T, Tuple3<? extends T1, ? extends T2, ? extends T3>> unzipper) { final Tuple3<? extends T1, ? extends T2, ? extends T3> value = unzipper.apply(node.getValue()); final io.vavr.collection.List<Tuple3<Node<T1>, Node<T2>, Node<T3>>> children = node.getChildren() .map(child -> unzip3(child, unzipper)); final Node<T1> node1 = new Node<>(value._1, children.map(t -> t._1)); final Node<T2> node2 = new Node<>(value._2, children.map(t -> t._2)); final Node<T3> node3 = new Node<>(value._3, children.map(t -> t._3)); return Tuple.of(node1, node2, node3); }
static <T> Stream<Node<T>> traverseInOrder(Node<T> node) { if (node.isLeaf()) { return Stream.of(node); } else { final io.vavr.collection.List<Node<T>> children = node.getChildren(); return children .tail() .foldLeft(Stream.<Node<T>> empty(), (acc, child) -> acc.appendAll(traverseInOrder(child))) .prepend(node) .prependAll(traverseInOrder(children.head())); } }