@@ -1121,6 +1121,62 @@ println("workingList2=$workingList2")*/
11211121 }
11221122 return destination
11231123 }
1124+
1125+ data class HierarchicalNode <T >(
1126+ val data : T ,
1127+ val hierarchyLevel : Int ,
1128+ var parent : HierarchicalNode <T >? = null
1129+ )
1130+ /* *
1131+ * Given a list of a hierarchical type [T], such that one [T] can be defined as the parent of another (potentially nested arbitrarily),
1132+ * return a list of [HierarchicalNode]s classifying the given [T]s as children and parents.
1133+ * For example, given a list of tasks, subtasks, sub-subtasks, etc., by defining a way to identify the level of
1134+ * hierarchy of a particular [T], this function can return a list of [HierarchicalNode]s representing that hierarchy.
1135+ * In this case, and example call could be:
1136+ * mutableListOf("-A","--1","--2","-B").mapToHierarchy({ it.count { it == '-' } }) { it.removePrefix("-") }
1137+ * */
1138+ fun <T , R > MutableList<T>.mapToHierarchy (
1139+ getHierarchicalLevel : (T ) -> Int ,
1140+ transform : (T ) -> R ,
1141+ ): List <HierarchicalNode <R >> {
1142+ val nodes = mutableListOf<HierarchicalNode <R >>()
1143+ while (isNotEmpty()) {
1144+ val thisElement = removeFirst()
1145+ val thisLevel = getHierarchicalLevel(thisElement)
1146+
1147+ val nextElement = firstOrNull()
1148+ val nextLevel = nextElement?.let (getHierarchicalLevel)
1149+
1150+ val parent = nodes.findLast { it.hierarchyLevel < thisLevel }
1151+ val thisNode = HierarchicalNode (transform(thisElement), thisLevel, parent)
1152+ if (parent == null ) nodes.add(thisNode) // add root
1153+ if (nextLevel != null ) {
1154+ when {
1155+ thisLevel < nextLevel -> nodes.add(
1156+ HierarchicalNode (
1157+ transform(nextElement),
1158+ nextLevel,
1159+ thisNode
1160+ )
1161+ ) // moving up levels of hierarchy, add next with parent as this
1162+ thisLevel > nextLevel -> nodes.add(
1163+ HierarchicalNode (
1164+ transform(nextElement),
1165+ nextLevel,
1166+ nodes.findLast { it.hierarchyLevel < nextLevel })
1167+ ) // moving down levels of hierarchy, find previous parent
1168+ else /* equal*/ -> nodes.add(
1169+ HierarchicalNode (
1170+ transform(nextElement),
1171+ nextLevel,
1172+ thisNode.parent
1173+ )
1174+ ) // same parent/level of hierarchy
1175+ }
1176+ }
1177+ }
1178+ return nodes.toList()
1179+ }
11241180
11251181 /* *
11261182 * A `val foo by lazy {}` alternative that supports vars, viz. `var foo = by LazyMutable {}`
0 commit comments