UNPKG

@applicaster/zapp-react-native-utils

Version:

Applicaster Zapp React Native utilities package

114 lines (96 loc) 3.5 kB
/* eslint-disable unused-imports/no-unused-vars */ import * as R from "ramda"; import { invariant } from "@applicaster/zapp-react-native-utils/errorUtils"; /** * shifts an array by the given offset. a negative offset will take items * from the end of the array and add them at the beginning, while a positive offset * will take an item at the beginning and shift it to the end * shiftArray(-1, [1,2,3,4]) => [4, 1, 2, 3] * shiftArray(1, [1,2,3,4]) => [2, 3, 4, 1] * an offset of 0 leaves the array unchanged * this function returns a new array and doesn't mutate the original one * curried function which can be invoked like offset => array => result * @param {Number} offset offset to shift the array * @param {Array<T>} array array to shift * @returns {Array<T>} */ export const shiftArray = R.curry( <T extends unknown>(offset: number, array: T[]): T[] => { return R.concat( R.slice(offset, R.length(array), array), R.slice(0, offset, array) ); } ); /** * Tries to remove an item from an array, and returns the array if the item is not found * @param {any} item to remove * @param {Array<any>} list to remove the item from * @returns {Array<any>} */ export function removeItemFromList<T extends unknown>(item: T, list: T[]): T[] { return R.compose( R.ifElse(R.equals(-1), R.always(list), R.remove(R.__, 1, list)), R.indexOf(item) )(list); } export const mapPromises = R.curry( <T extends unknown, S extends unknown>( fn: (value: T, index?: number) => Promise<S>, values: T[] ): Promise<S[]> => Promise.all(R.addIndex(R.map)(R.nAry(2, fn), values)) ); const waitForPromiseAndRun = R.curryN( 3, async <T extends unknown, S extends unknown>( fn: (currentValue: T, previousValue: S, index?: number) => Promise<S>, previousPromise: Promise<S>, currentValue: T, index: number ) => { const previousValue = await previousPromise; return fn(currentValue, previousValue, index); } ); export const reducePromises = R.curry( <T extends unknown, S extends unknown>( fn: (current: T, previous: S, index?: number) => Promise<S>, initialValue: S, values: T[] ): Promise<S> => R.addIndex(R.reduce)( waitForPromiseAndRun<T, S>(fn), Promise.resolve(initialValue), values ) ); export const mapAndSplit = R.curry( <T extends unknown, S extends unknown>( mapperFn: (T) => S, chunks: number ): S[][] => R.compose(R.splitEvery(chunks), R.map(mapperFn)) ); export const isLast = (index: number, length: number): boolean => index >= length - 1; export const isFirst = (index: number): boolean => index <= 0; export const isIndexInRange = (index: number, length: number): boolean => { if (length <= 0) return false; if (index < 0) return false; return index + 1 <= length; }; export const makeListOfIndexes = (size: number): number[] => Array.from({ length: size }, (_, index) => index); export const makeListOf = (value: unknown, size: number): number[] => { return Array(size).fill(value); }; /** Checks if a value is a non-empty array */ export function isFilledArray(value: unknown): boolean { return R.is(Array, value) && R.length(value) > 0; } // get random item from the list export const sample = (xs: unknown[]): unknown => { invariant(R.is(Array, xs), `input value is not a array: ${xs}`); invariant(isFilledArray(xs), `input array is empty: ${xs}`); const index = Math.floor(Math.random() * xs.length); return xs[index]; };