Skip to content

Commit

Permalink
new container trees and named container trees
Browse files Browse the repository at this point in the history
  • Loading branch information
VuzZis committed Feb 11, 2025
1 parent fd17ed7 commit cf7975b
Show file tree
Hide file tree
Showing 6 changed files with 332 additions and 0 deletions.
9 changes: 9 additions & 0 deletions src/main/java/pro/komaru/tridot/core/struct/Structs.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package pro.komaru.tridot.core.struct;


import pro.komaru.tridot.core.struct.data.Seq;
import pro.komaru.tridot.core.struct.func.Cons;
import pro.komaru.tridot.core.struct.func.Func;
import pro.komaru.tridot.core.struct.func.Prov;
Expand All @@ -14,6 +15,9 @@ public static <A> Prov<A> nil(){
return () -> null;
}

public static <A,B> A cast(B obj) {
return (A) obj;
}
public static <T> T or(T a, T b) {
if(a == null) return b;
return a;
Expand Down Expand Up @@ -54,6 +58,11 @@ public static <K,V> HashMap<K,V> map(Object... objs) {
}
return map;
}
public static <A> A[] pop(A[] def) {
var n = Seq.with(def);
n.slice();
return n.toArray();
}
public static <K,V> HashMap<V,K> revMap(HashMap<K,V> mapOrig) {
HashMap<V,K> map = new HashMap<>();
mapOrig.forEach((k,v) -> map.put(v,k));
Expand Down
5 changes: 5 additions & 0 deletions src/main/java/pro/komaru/tridot/core/struct/data/Seq.java
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,11 @@ public static <T> Seq<T> withArrays(Object... arrays){
return result;
}

/** @see #Seq(Object[]) */
public static <T> Seq<T> with(){
return new Seq<>();
}

/** @see #Seq(Object[]) */
public static <T> Seq<T> with(T... array){
return new Seq<>(array);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,198 @@
package pro.komaru.tridot.core.struct.data.tree;

import pro.komaru.tridot.core.struct.data.Seq;
import pro.komaru.tridot.core.struct.func.Boolf;

import java.util.LinkedList;
import java.util.Queue;

@SuppressWarnings("rawtypes,unchecked")
public class ContainerTree<A> implements ITree<A> {
private final Seq<A> children;
private final Seq<ContainerTree<A>> containers;

public ContainerTree<A> parent = null;

public ContainerTree() {
children = Seq.with();
containers = Seq.with();
}


/**
* Adds all elements as children of this container tree
* @param all elements to add
*/
@SafeVarargs
public final ContainerTree<A> add(A... all) {
children.add(all);

return this;
}
/**
* Adds element as a child of this container tree
* @param child element to add
*/
public ContainerTree<A> add(A child) {
children.add(child);
return this;
}

/**
* Adds element as a subcontainer of this container tree
* @param child element to add
*/
public ContainerTree<A> add(ContainerTree<A> child) {
containers.add(child);
child.parent = this;
return this;
}

/**
* Adds all elements as children of this container tree if they don't exist yet
* @param all elements to add
*/
@SafeVarargs
public final ContainerTree<A> addUnique(A... all) {
for (A a : all) {
addUnique(a);
}
return this;
}
/**
* Adds element as a child of this container tree if it doesn't exist yet
* @param child element to add
*/
public ContainerTree<A> addUnique(A child) {
children.addUnique(child);
return this;
}

/**
* Finds a child of this container using a filter function
* @param filter filter function
* @return child object
*/
@Override
public A child(Boolf<A> filter) {
return children().find(filter);
}
/**
* Finds a child in all containers of this tree using a filter function
* @param filter filter function
* @return child object
*/
@Override
public A childDeep(Boolf<A> filter,boolean depthSearch) {
A child = children().find(filter);
if(depthSearch) {
if (child == null) {
for (ITree<A> container : containers) {
A other = container.childDeep(filter);
if (other != null) {
return other;
}
}
}
} else {
Queue<ContainerTree<A>> queue = new LinkedList<>();
queue.add(this);

while (!queue.isEmpty()) {
ContainerTree<A> current = queue.poll();
A other = current.children().find(filter);
if (other != null) {
return other;
}
queue.addAll(current.containers.list());
}
}
return child;
}

/**
* Finds a child in all containers of this tree using a filter function, in a BFS method
* @param filter filter function
* @return child object
*/
@Override
public A childDeep(Boolf<A> filter) {
return childDeep(filter,false);
}

/**
* Clears all tree
*/
@Override
public void clean() {
children().clear();
containers.each(e -> e.parent = null); //bye-bye!
containers().clear();
}


/**
* @return Children Seq
*/
@Override
public Seq<A> children() {
return children;
}

/**
* @return Children of this tree and subcontainers' children
*/
@Override
public Seq<A> childrenDeep() {
Seq<A> all = Seq.with();
all.addAll(children());
for (ITree<A> container : containers())
all.addAll(container.childrenDeep());
return all;
}

/**
* @return Subcontainer Seq
*/
public Seq<ContainerTree<A>> containers() {
return containers;
}

/**
* @return All containers of this tree
*/
public Seq<ContainerTree<A>> containersDeep() {
Seq<ContainerTree<A>> all = Seq.with();
all.addAll(containers());
for (ContainerTree<A> other : containers())
all.addAll(other.containers);
return all;
}


@Override
public String toString() {
String name = this instanceof NamedContTree<?> a ? a.name : "***";
StringBuilder sb = new StringBuilder("\u001B[33m[" + name + "]\u001B[0m");
sb.append("\n");
for (ContainerTree<A> cont : containers) {
Seq<String> lines = Seq.with(cont.toString().lines().map(e -> " " + e).toList());
if(!lines.isEmpty()) {
lines.set(0,lines.get(0).replaceFirst(" ",""));
}
sb.append("\u001B[33m-\u001B[0m");
sb.append(String.join("\n", lines));
sb.append("\n");
}
for (A child : children) {
Seq<String> lines = Seq.with(child.toString().lines().map(e -> " " + e).toList());
if(!lines.isEmpty()) {
lines.set(0,lines.get(0).replaceFirst(" ",""));
}
sb.append("\u001B[37m*\u001B[0m");
sb.append(String.join("\n", lines));
sb.append("\n");
}
return sb.toString();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package pro.komaru.tridot.core.struct.data.tree;

public interface INamedTree {
String name();
}
35 changes: 35 additions & 0 deletions src/main/java/pro/komaru/tridot/core/struct/data/tree/ITree.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package pro.komaru.tridot.core.struct.data.tree;

import pro.komaru.tridot.core.struct.data.Seq;
import pro.komaru.tridot.core.struct.func.Boolf;

public interface ITree<A> {
Seq<A> children();
Seq<A> childrenDeep();

A child(Boolf<A> filter);


/**
* Deepfinding a child using a filter in either BFS or DFS
* @param filter filter function
* @param depthSearch if true, then it uses DFS instead of BFS
* @return child object
*/
A childDeep(Boolf<A> filter, boolean depthSearch);

default A childDeep(Boolf<A> filter) {
return childDeep(filter,false);
};
default A child(Boolf<A> filter, boolean deep, boolean depthSearch) {
return deep ? childDeep(filter,depthSearch) : child(filter);
}
default A child(Boolf<A> filter, boolean deep) {
return child(filter,deep,false);
}

/**
* Clears all tree
*/
void clean();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
package pro.komaru.tridot.core.struct.data.tree;

import pro.komaru.tridot.core.struct.Structs;
import pro.komaru.tridot.core.struct.data.Seq;

import java.util.HashMap;

public class NamedContTree<A> extends ContainerTree<A> implements INamedTree {
public final String name;

private final HashMap<String,Object> PATH_CACHE =
new HashMap<>();

public NamedContTree(String name) {
this.name = name;
}

@Override
public NamedContTree<A> add(A child) {
return (NamedContTree<A>) super.add(child);
}

@Override
public NamedContTree<A> add(ContainerTree<A> child) {
return (NamedContTree<A>) super.add(child);
}

@Override
public NamedContTree<A> addUnique(A child) {
return (NamedContTree<A>) super.addUnique(child);
}

public NamedContTree<A> cd(boolean autoCreate, String... path) {
if(path == null || path.length == 0) return this;
if(path[0].equals("..")) return ((NamedContTree<A>) parent).cd(autoCreate,Structs.pop(path));
for (NamedContTree<A> cont : namedContainers()) {
if(cont.name.equals(path[0]))
return cont.cd(autoCreate,Structs.pop(path));
}
if(autoCreate) {
NamedContTree<A> newTree = new NamedContTree<>(path[0]);
containers().add(newTree);
newTree.parent = this;
return newTree.cd(true,Structs.pop(path));
}
return null;
}
public NamedContTree<A> cd(boolean autoCreate,String path) {
return cd(autoCreate,path.split("/"));
}
public NamedContTree<A> cd(String... path) {
return cd(true,path);
}
public NamedContTree<A> cd(String path) {
return cd(true,path);
}

public static void main(String[] args) {
NamedContTree<String> main = new NamedContTree<>("main");
main
.cd("a")
.add("A section!")
.cd("../b")
.add("B section!")
.cd("../a/c")
.add("C section!")
.cd("../..")
.add("End section!");
System.out.println(main);
}

public Seq<NamedContTree<A>> namedContainers() {
return Structs.cast(containers().select(e -> e instanceof NamedContTree));
}

@Override
public String name() {
return name;
}
}

0 comments on commit cf7975b

Please sign in to comment.