sortedByOutputDependency method

List<Node<T>> sortedByOutputDependency({
  1. int? maxDepth,
  2. bool bfs = false,
})

Implementation

List<Node<T>> sortedByOutputDependency({int? maxDepth, bool bfs = false}) {
  var nodesOutputs = outputsInDepth(maxDepth: maxDepth, bfs: bfs);

  var nodesOutputsEntries = nodesOutputs.entries.toList();

  var alone = nodesOutputsEntries.where((e) => e.value.isEmpty).keys.toList();

  alone = alone.sortedByInputDepth();

  if (alone.length == nodesOutputsEntries.length) {
    return alone;
  }

  nodesOutputsEntries.removeWhere((e) => alone.contains(e.key));

  var entriesIntersections = nodesOutputsEntries.map((e) {
    var entriesOutputs = e.value;
    var others = nodesOutputsEntries.where((e2) => e2 != e);

    var intersections = others
        .map((other) =>
            MapEntry(other.key, entriesOutputs.intersection(other.value)))
        .where((other) => other.value.isNotEmpty);

    return MapEntry(e.key, Map.fromEntries(intersections));
  }).toList();

  var isolated =
      entriesIntersections.where((e) => e.value.isEmpty).keys.toList();

  nodesOutputsEntries.removeWhere((e) => isolated.contains(e.key));

  isolated = isolated.sortedByOutputsDepth().toReversedList(growable: false);

  var sideRoots = nodesOutputsEntries
      .map((e) => MapEntry(e.key, e.key.sideRoots()))
      .toList();

  var withoutSideRoots =
      sideRoots.where((e) => e.value.isEmpty).keys.toList(growable: false);

  nodesOutputsEntries.removeWhere((e) => withoutSideRoots.contains(e.key));

  var rest = nodesOutputsEntries.keys.sortedByOutputsDepth().toReversedList();

  var nodes = [...alone, ...isolated, ...withoutSideRoots, ...rest].toList();
  return nodes;
}