import * as _ from "lodash"; export interface IStringMap { [key: string]: V; } export const omitFunctions = (obj: object) => _.omit(obj, _.functions(obj)); export const isEqualWithoutFunctions = (a: any, b: any) => _.isEqual(omitFunctions(a), omitFunctions(b)); export const wasShuffled = (original: any[], shuffled: any[], selector: string): boolean => // @ts-ignore _.chain(_.intersectionBy(original, shuffled, selector)) // The new array is shuffled if... .thru(intersection => intersection.length === original.length && intersection.length === shuffled.length) // ...no elements have been added or removed .thru(__ => __ && _.some(original, (value, index) => _.get(value, selector) !== _.get(shuffled[index], selector))) // ...and at least one element is in a different order .thru(__ => __ && _.every(original, (value, index) => _.isEqual(value, _.find(shuffled, (shuffledValue) => _.get(shuffledValue, selector) === _.get(value, selector))))) // ...yet all values are equal .value(); export const filterNil = (arr: T[]) => _.filter(arr, (value: T) => !_.isNil(value)); /** * [1,2,3,4,5] // 3,4,2,5,1 * * @param middleIndex - Optionally provided index to consider middle */ export const iterateMiddleOut = (arr: T[], callback: (item: T) => void, middleIndex?: number) => { // Guard against nil or bad values if (_.isNil(arr) || _.isNil(callback) || !_.isArray(arr) || !_.isFunction(callback)) return; // Start at middle index const index = _.isNumber(middleIndex) ? middleIndex : Math.floor((arr.length - 1) / 2); let topIndex = index + 1; let bottomIndex = index; // Iterate until both index have reached their limit while (topIndex < arr.length || bottomIndex > -1) { // We call bottom first as that's the middle if (bottomIndex > -1) callback(arr[bottomIndex]); if (topIndex < arr.length) callback(arr[topIndex]); // Update indexes topIndex++; bottomIndex--; } }