Skip to content

Commit

Permalink
feat(grid): move traversers to traversers folder and add utils folder…
Browse files Browse the repository at this point in the history
… with forEach and map

The `forEach()` function is aliased to `tap()`. These utils are curried and used in `Grid.each()`
and `Grid.map()`.
  • Loading branch information
flauwekeul committed Apr 22, 2021
1 parent 65750d0 commit 751be5a
Show file tree
Hide file tree
Showing 10 changed files with 35 additions and 23 deletions.
36 changes: 14 additions & 22 deletions src/grid/grid.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { createHex, CubeCoordinates, equals, Hex, HexCoordinates } from '../hex'
import { offsetFromZero } from '../utils'
import { RECTANGLE_DIRECTIONS } from './constants'
import { Compass, RectangleOptions, Traverser } from './types'
import { forEach, map } from './utils'

interface InternalTraverser<T extends Hex> {
(this: Grid<T>): Iterable<T>
Expand All @@ -25,37 +26,28 @@ export class Grid<T extends Hex> {
return Grid.of(this.hexPrototype, traverser.bind(this))
}

// todo: use generic functions for these kinds of operations
// something like https://github.com/benji6/imlazy or https://github.com/lodash/lodash/wiki/FP-Guide
each(fn: (hex: T) => void) {
const each: InternalTraverser<T> = () => {
for (const hex of this.traverser()) {
fn(hex)
}
return this.traverser()
}
return this.clone(each)
// todo: make it point-free:
// const each: InternalTraverser<T> = forEach(fn)
// then in clone():
// return Grid.of(this.hexPrototype, () => traverser(this.traverser()))
// or this, but then traverser needs to be passed `this.traverser()` at the right moment (in the for of loop):
// return Grid.of(this.hexPrototype, traverser)
return this.clone(() => forEach(fn)(this.traverser()))
}

map(fn: (hex: T) => T) {
const map: InternalTraverser<T> = () => {
const result: T[] = []
for (const hex of this.traverser()) {
result.push(fn(hex))
}
return result
}
return this.clone(map)
return this.clone(() => map(fn)(this.traverser()))
}

// todo: alias to take or takeUntil?
run(stopFn: (hex: T) => boolean = () => false) {
for (const hex of this.traverser()) {
forEach<T>((hex) => {
if (stopFn(hex)) {
return this
}
}
return this // or clone()? todo: when to return clone and when not?
})(this.traverser())
return this
}

rectangle({
Expand All @@ -68,7 +60,7 @@ export class Grid<T extends Hex> {
const [firstCoordinate, secondCoordinate, thirdCoordinate] = RECTANGLE_DIRECTIONS[direction]
const [firstStop, secondStop] = this.hexPrototype.isPointy ? [width, height] : [height, width]
const relativeOffset = (coordinate: number) => offsetFromZero(this.hexPrototype.offset, coordinate)
const traverser: Traverser<T> = (cursor) => {
const rectangle: Traverser<T> = (cursor) => {
const result: HexCoordinates[] = []
let _cursor = cursor
for (let second = 0; second < secondStop; second++) {
Expand All @@ -85,7 +77,7 @@ export class Grid<T extends Hex> {
}
return result
}
return this.traverse(traverser)
return this.traverse(rectangle)
}

// fixme: when topLeft > bottomRight
Expand Down
3 changes: 2 additions & 1 deletion src/grid/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
export * from './constants'
export * from './functions'
export * from './grid'
export * from './traversers'
export * from './types'
export * from './utils'
File renamed without changes.
2 changes: 2 additions & 0 deletions src/grid/functions/index.ts → src/grid/traversers/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
export * from './at'
export * from './branch'
export * from './concat'
export * from './move'
export * from './rectangle'
export * from './repeat'
File renamed without changes.
File renamed without changes.
File renamed without changes.
8 changes: 8 additions & 0 deletions src/grid/utils/forEach.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
export const forEach = <T>(fn: (value: T) => void) => (iterable: Iterable<T>) => {
for (const value of iterable) {
fn(value)
}
return iterable
}

export const tap = forEach
2 changes: 2 additions & 0 deletions src/grid/utils/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from './forEach'
export * from './map'
7 changes: 7 additions & 0 deletions src/grid/utils/map.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export const map = <T>(fn: (value: T) => T) => (iterable: Iterable<T>) => {
const result: T[] = []
for (const value of iterable) {
result.push(fn(value))
}
return result
}

0 comments on commit 751be5a

Please sign in to comment.