valueOfFirstDescendantOf<T, V> function

V? valueOfFirstDescendantOf<T, V>(
  1. T node, {
  2. required bool where(
    1. T
    ),
  3. required V defaultValue,
  4. required V? getValue(
    1. T
    ),
  5. required Iterable<T>? childrenOf(
    1. T
    ),
  6. bool isValueInherited = true,
})

Walks the given node and its descendants in pre-order and returns the value (using getValue) of the first node (including the initial node) where the where function returns true. If no matching node is found, null is returned.

If the value of the matching node is null, and isValueInherited is true, the default, the value of the matching node's parent is returned, or its parent, if it is also null, and so on, all the way up the tree. If all the values are null, the defaultValue is returned.

If the value of the matching node is null and isValueInherited is set to false, the defaultValue is returned.

Implementation

V? valueOfFirstDescendantOf<T, V>(
  T node, {
  required bool Function(T) where,
  required V defaultValue,
  required V? Function(T) getValue,
  required Iterable<T>? Function(T) childrenOf,
  bool isValueInherited = true,
}) {
  if (where(node)) {
    return getValue(node) ?? defaultValue;
  } else {
    // Walk its descendants in pre-order, looking for the first match.
    final children = childrenOf(node);
    if (children != null) {
      final value = (isValueInherited ? getValue(node) : null) ?? defaultValue;
      for (final child in children) {
        final childValue = valueOfFirstDescendantOf(child,
            where: where,
            defaultValue: value,
            getValue: getValue,
            childrenOf: childrenOf,
            isValueInherited: isValueInherited);
        if (childValue != null) return childValue;
      }
    }
  }

  return null; // ignore: avoid_returning_null
}