iterateWithFilter static method

Iterable<PlutoRow> iterateWithFilter(
  1. Iterable<PlutoRow> rows, {
  2. bool filter(
    1. PlutoRow
    )?,
  3. Iterator<PlutoRow>? childrenFilter(
    1. PlutoRow
    )?,
  4. bool iterateAll = true,
})

Traversing the group rows of rows according to the filter condition.

If childrenFilter is passed, the traversal condition of child rows is applied.

If iterateAll is true, the filtering condition applied to the child row of each group is ignored and Iterate through the entire row.

Implementation

static Iterable<PlutoRow> iterateWithFilter(
  Iterable<PlutoRow> rows, {
  bool Function(PlutoRow)? filter,
  Iterator<PlutoRow>? Function(PlutoRow)? childrenFilter,
  bool iterateAll = true,
}) sync* {
  if (rows.isEmpty) return;

  final List<Iterator<PlutoRow>> stack = [];

  Iterator<PlutoRow>? currentIter = rows.iterator;

  Iterator<PlutoRow>? defaultChildrenFilter(PlutoRow row) {
    return row.type.isGroup
        ? iterateAll
            ? row.type.group.children.originalList.iterator
            : row.type.group.children.iterator
        : null;
  }

  final filterChildren = childrenFilter ?? defaultChildrenFilter;

  while (currentIter != null || stack.isNotEmpty) {
    bool hasChildren = false;

    if (currentIter != null) {
      while (currentIter!.moveNext()) {
        if (filter == null || filter(currentIter.current)) {
          yield currentIter.current;
        }

        final Iterator<PlutoRow>? children = filterChildren(
          currentIter.current,
        );

        if (children != null) {
          stack.add(currentIter);
          currentIter = children;
          hasChildren = true;
          break;
        }
      }
    }

    if (!hasChildren) {
      currentIter = stack.lastOrNull;
      if (currentIter != null) stack.removeLast();
    }
  }
}