UNPKG

rubico

Version:

[a]synchronous functional programming

110 lines (105 loc) 3.4 kB
const __ = require('../_internal/placeholder') const curry2 = require('../_internal/curry2') const curry3 = require('../_internal/curry3') const thunkify2 = require('../_internal/thunkify2') const thunkify5 = require('../_internal/thunkify5') const thunkConditional = require('../_internal/thunkConditional') const isPromise = require('../_internal/isPromise') const isArray = require('../_internal/isArray') const arraySome = require('../_internal/arraySome') const arrayPush = require('../_internal/arrayPush') const funcConcatSync = require('../_internal/funcConcatSync') const noop = require('../_internal/noop') const symbolIterator = require('../_internal/symbolIterator') const symbolAsyncIterator = require('../_internal/symbolAsyncIterator') /** * @name differenceWithArrayAsync * * @synopsis * ```coffeescript [specscript] * differenceWithArrayAsync( * comparator (any, any)=>Promise|boolean, * allValues Array, * array Array, * result Array, * index number, * ) -> result Promise<Array> * ``` */ const differenceWithArrayAsync = async function ( comparator, allValues, array, result, index ) { const allValuesLength = allValues.length while (++index < allValuesLength) { const item = allValues[index] let doesItemExistByComparator = arraySome(array, curry2(comparator, item, __)) if (isPromise(doesItemExistByComparator)) { doesItemExistByComparator = await doesItemExistByComparator } if (!doesItemExistByComparator) { result.push(item) } } return result } /** * @name differenceWithArray * * @synopsis * ```coffeescript [specscript] * differenceWithArray( * comparator (any, any)=>Promise|boolean, * allValues Array, * array Array, * ) -> someOrAllValues Promise|Array * ``` */ const differenceWithArray = function (comparator, allValues, array) { const allValuesLength = allValues.length, result = [] let index = -1 while (++index < allValuesLength) { const item = allValues[index], doesItemExistByComparator = arraySome(array, curry2(comparator, item, __)) if (isPromise(doesItemExistByComparator)) { return doesItemExistByComparator.then(funcConcatSync( curry3(thunkConditional, __, noop, thunkify2(arrayPush, result, item)), thunkify5(differenceWithArrayAsync, comparator, allValues, array, result, index))) } else if (!doesItemExistByComparator) { result.push(item) } } return result } /** * @name differenceWith * * @synopsis * ```coffeescript [specscript] * differenceWith( * comparator (any, any)=>Promise|boolean, * allValues Array, * )(values Array) -> someOrAllValues Array * ``` * * @description * Create an array of all the values in an array that are not in another array as dictated by a comparator. * * ```javascript [playground] * import differenceWith from 'https://unpkg.com/rubico/dist/x/differenceWith.es.js' * import isDeepEqual from 'https://unpkg.com/rubico/dist/x/isDeepEqual.es.js' * * console.log( * differenceWith(isDeepEqual, [{ a: 1 }, { b: 2 }, { c: 3 }])([{ b: 2 }]), * ) // [{ a: 1 }, { c: 3 }] * ``` */ const differenceWith = ( comparator, allValues, ) => function excludingValues(values) { if (isArray(values)) { return differenceWithArray(comparator, allValues, values) } throw new TypeError(`${values} is not an Array`) } module.exports = differenceWith