All files / src/ops/ordinal breadthFirst.ts

100% Statements 32/32
100% Branches 5/5
100% Functions 2/2
100% Lines 32/32

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 461x 1x 1x 1x 1x 1x 1x 1x         1x 1x 5x 5x   5x 6x 6x   6x 6x 6x 6x 6x 6x 6x   6x   6x 6x         1x 1x 2x 2x   2x 3x 3x  
import {type NonEmptyArray2, transpose} from '#Array'
import {Paths} from '#codec'
import {pipe} from '#Function'
import {map, type Tree} from '#tree'
import {Array, Number, Order} from '#util'
import {flow, Tuple} from 'effect'
import {flatten} from 'effect/Option'
import {zipUniqueOrdinal} from './zipUniqueOrdinal.js'
 
/**
 * @category internal
 */
export const annotateBreadthFirst =
  <A>(
    orderA: Order.Order<A>,
    start = 0,
  ): ((self: Tree<A>) => Tree<[A, number]>) =>
  self => {
    const [head, ...tail] = pipe(self, Paths.encode, transpose.nonEmpty)
    const zip = zipUniqueOrdinal(orderA)
 
    const paths = pipe(
      tail,
      Array.scan(zip(start)(head), ([, index], options) => zip(index)(options)),
      Array.map(Tuple.getFirst),
      transpose,
      Array.map(flow(Array.map(flatten), Array.getSomes)),
    ) as NonEmptyArray2<[A, number]>
 
    const order = Order.tuple(orderA, Number.Order) as Order.Order<[A, number]>
 
    return pipe(paths, Paths.decode(order))
  }
 
/**
 * @category internal
 */
export const replaceBreadthFirst =
  <A>(
    orderA: Order.Order<A>,
    start?: number,
  ): ((self: Tree<A>) => Tree<number>) =>
  self => {
    return pipe(self, annotateBreadthFirst(orderA, start), map(Tuple.getSecond))
  }