Foray

Foray /fɔːr əˈreɪ/ n. informal

  1. A venture or initiative to alter the manner in which individuals and systems organize, manage, and interact with lists n' stuff.

foray

Pass this an array and it will return an interface with enhanced methods for that array.

foray(array: array)
Parameters
array (array)
Example
const lookup = { c: 'you found me' };
  const result = foray(['a', 'b', 'c']).findMapped((key) => lookup[key]);
  console.log(result); // 'you found me';

forayProxy

Wraps the passed array in a Proxy, returning an object that can be used just like the original array, but with added methods provided by foray.

forayProxy(array: Array): Object
Parameters
array (Array) The array to wrap in a foray proxy.
Returns
Object: A Proxy object that behaves like the array, but with added foray methods.
Example
const array = foray([1, 2, 3, 4]);
    array.push(5); // you can use standard array methods
    const output = array.findMapped((v) => { // ...and foray ones
        if (v * 2 === 8) return { found: true };
    });
    console.log(output); // { found: true }

forayWeakCache

Wraps the passed array in a foray object and stores it in a WeakMap. If the same array is passed again, the function will return the stored foray instance from the WeakMap, instead of creating a new one. This provides a performance optimization for repeat calls with the same array.

forayWeakCache(array: Array): Object
Parameters
array (Array) The array to wrap in a foray object.
Returns
Object: A foray object. If the same array has been passed before, the previous foray object will be returned.
Example
const array = [1, 2, 3, 4];
    // each time you want access to foray methods, just wrap the array
    const output1 = foray(array).findMapped((v) => {
        if (v * 2 === 8) return { found: 8 };
    });
    const output2 = foray(array).findMapped((v) => {
        if (v * 2 === 6) return { found: 6 };
    });
    console.log(output1); // { found: 8 }
    console.log(output2); // { found: 6 }

fn

Allows to create a function that is designed to manipulate an array using atomic functions.

fn(atoms: ...function)
Parameters
atoms (...function)

Atoms

Atoms are simple functions that can be combined to make more complicated logic.

useLog

useLog simply logs the current item and then returns it. This can be useful for debugging.

useLog(params: object)
Parameters
params (object)
Name Description
params.prefix string (default '')
params.suffix string (default '')
params.logFn any (default v=>console.log(v))

useEscape

useEscape will stop the fn() process and immediately return if the checkFn returns truthy.

useEscape(checkFn: function)
Parameters
checkFn (function)

useMapper

useMapper just applies a simple mapping function.

useMapper(mapFn: function)
Parameters
mapFn (function)

useReducer

useReducer applies a simple reduction function. It assumes the initial value for the reduction is in the first argument slot.

useReducer(reduceFn: function)
Parameters
reduceFn (function)

useSlice

useSlice acts like the Array.prototype.slice method for the output array. It sets the start and end positions of the output array as it iterates through the input items. If an item's position falls outside the specified slice range, the function returns undefined and adjusts the output array accordingly. It can take one or two arguments, and handles both positive and negative indices.

Note: if you are looking to just handle slicing at the end of your atom you should probably use a hook instead.

useSlice(start: number, end: number?): function
Parameters
start (number) The start index. supports negative values that operate backwards from the end of the string.
end (number? = undefined) The end index. supports negative values that operate backwards from the end of the string.
Returns
function: A function to be used as an atom with fn() .

Initialisers

Initialisers are used to construct atoms during a foray method execution, rather than before. This allows atoms to receive parameters at runtime.

makeWithArg

This is an example of an atom initialiser that will initialise the atom during the runtime of the fn().

makeWithArg(uninitialisedAtomFn: function, offset: number)
Parameters
uninitialisedAtomFn (function)
offset (number)

Decorators

Whilst only a slight distinction, decorator atoms are similar to atoms, but their purpose is to modify the behaviour of existing atoms.

withLog

withLog is a decorator that logs the output of a passed-in atom function.

withLog(atomFn: function, logFn: function)
Parameters
atomFn (function)
logFn (function = (v)=>console.log(v))
Example
fn(
      cohesive(
        withLog(makeWithArg(useMapper, 0)),
        useEscape(v => v),
      )
    );

withOutput

This is an example of an atom decorator that will modify the behaviour of an already initialised atom. withOutput specifically takes an output that has been generated by the fn() and pipes that as an input to the passed in atomFn.

withOutput(atomFn: function, offset: number)
Parameters
atomFn (function)
offset (number)

Cursors

Cursors are what allows fn() to navigate around the atoms it needs to process. The default cursor is designed to handle stopping the process early and controlling inputs and outputs.

ForayCursor

The class just tracks the internal cursor used inside fn(). Atoms can use this to alter the inputs and outputs, and to decide when we should return.

new ForayCursor(params: object)
Parameters
params (object) a params wrapper
Name Description
params.args any (default [])
params.atoms any
params.array any
params.entries any
params.outputs any (default [])

Hooks

Hooks allow triggering functions before and after array processing.

addAfterAllHook

Adds the afterAllHook to trigger once method has finished processing the target array.

addAfterAllHook(method: function, afterAllHook: function)
Parameters
method (function)
afterAllHook (function)
Example
// Reduce our outputs to the final one and return a single value.
addAfterAllHook(reduceMapped, (cursor) => {
  cursor.outputs = cursor.outputs.slice(-1);
  ([cursor.returnValue] = cursor.outputs);
});

addAfterHook

Adds the afterHook to trigger once method has processed through one loop of the target array.

addAfterHook(method: function, afterHook: function)
Parameters
method (function)
afterHook (function)

addBeforeAllHook

Adds the beforeAllHook to trigger once before any array processing by method

addBeforeAllHook(method: function, beforeAllHook: function)
Parameters
method (function)
beforeAllHook (function)

addBeforeHook

Adds the beforeHook to trigger before each loop of the array as method processes.

addBeforeHook(method: function, beforeHook: function)
Parameters
method (function)
beforeHook (function)

getHooks

Grab out the list of hooks attached to method based on hookCategoryName. If no hookCategoryName provided, then the entire hooks object is returned.

getHooks(method: function, hookCategoryName: string)
Parameters
method (function)
hookCategoryName (string = undefined)

setupHooks

Extend a method created by fn() to have hooks.

setupHooks(method: function)
Parameters
method (function)

triggerHooks

Trigger hooks based on hook category name.

triggerHooks(method: function, hookCategoryName: any, cursor: any)
Parameters
method (function)
hookCategoryName (any)
cursor (any)

Operators

Operators allow for conditional processing of atoms.

and

Pass the input to multiple functions, in order, the output will be from the last function to return a truthy value.

and(fns: ...function)
Parameters
fns (...function)
Static Members
configure(params)

cohesive

Combine more than one atom together, similar to pipe(), but making sure to manage outputs as we go.

cohesive(atoms: ...function)
Parameters
atoms (...function)

or

Pass the input to multiple functions, in order, the output will be from the first function to return a truthy value.

or(fns: ...function)
Parameters
fns (...function)
Static Members
configure(params)

pipe

Typical implementation of pipe. This is more basic than cohesive.

Passes the input to multiple functions, in left-to-right order, the output of the first function is passed to the next. The final output will be the returned value from the last processed function.

pipe(fns: ...function)
Parameters
fns (...function)

pipeWhile

Pass the input to multiple functions, in left-to-right order, the output of the first function is passed to the next. If a falsey value is encountered the processing stops and returns. The final output will be the returned value from the last processed function.

A good use-case for this atom would be passing your input through a list of functions that replace tokens. It will continue on replacing, returning the modified input. If you encounter something that doesn't validate you can return a falsey value to halt processing.

It might also be that falsey isn't good enough for your use-case. If so, you can create a configured version using pipeWhile.configure({ isTruthyFn }). This allows you to control what is seen as truthy, anything outside of this will halt the processing.

pipeWhile(fns: ...function)
Parameters
fns (...function)
Static Members
configure(params)

API Methods

These are the methods that can be returned by a call to foray([])

findMapped

findMapped - allows you to find() that also map()s, but will be more efficient than running [].map(x).find(x) for finds that occur before the end of the array, because it maps as it goes.

findMapped
Parameters
mapFn (function) this will be the map function, on returning a truthy value, the processing will stop, and the result returned.

get

get - simple offset getter.

get(offset: number)
Parameters
offset (number = 0)

getReversed

getReversed - simple reversed offset getter.

getReversed(offset: number)
Parameters
offset (number = 0)

reduceMapped

Map and reduce at the same time!! "Where we're going, roads aren't even a concept..."

reduceMapped
Parameters
mapFn (function)
reduceFn (function)
Example
const data = foray([1, 2, 3, 4]);
    const sumOfSquares = data.reduceMapped(
        x => x * x, // square each number
        (acc, x) => acc + x // sum the squares
    );
    console.log(sumOfSquares); // Outputs 30

set

set - simple offset setter.

set(key: number, value: any)
Parameters
key (number)
value (any)