Codibre/fluent-iterable

View on GitHub
src/recipes/filter-recipe.ts

Summary

Maintainability
A
0 mins
Test Coverage
A
100%
import { AnyIterable } from 'augmentative-iterable';
import {
  AnyMapper,
  isAnyOrderAssured,
  keepOrderAssuring,
  ResolverType,
} from '../types-internal';
import { prepare } from '../types-internal/prepare';
import { identity } from '../utils';
import { augmentIterableRecipe } from './augment-iterable-recipe';

export function filterRecipe(
  filterIterable: Function,
  takeWhileIterable: Function,
  resolver: ResolverType,
) {
  const baseFilter = augmentIterableRecipe(filterIterable);
  const takeWhile = augmentIterableRecipe(takeWhileIterable);

  return function <T>(
    this: AnyIterable<T>,
    basePredicate: AnyMapper<any> = identity,
  ) {
    const predicate = prepare(basePredicate);
    if (isAnyOrderAssured(predicate, this)) {
      let alreadyTrue = false;
      let lastResult = false;
      const takeWhilePredicate = (t: any) =>
        resolver(predicate(t), (result) => {
          alreadyTrue = alreadyTrue || result;
          lastResult = result;

          return !alreadyTrue || lastResult;
        });
      const action = () => lastResult;
      return keepOrderAssuring(
        baseFilter.call(takeWhile.call(this, takeWhilePredicate), action),
        this,
      );
    }

    return baseFilter.call(this, predicate);
  };
}