Last active
July 3, 2019 08:14
-
-
Save erkobridee/dc3c3521216f0ed006ab5ee78098abdb to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
type TJSObject = { [key: string]: any }; | |
type TJSValue = TJSObject | any; | |
type TArrayFilter<T> = (x: T) => boolean; | |
const TO_STRING = {}.toString; | |
const isObjectBasicCheck = <T extends object>(value: any): value is T => value !== null && typeof value === 'object'; | |
const isObject = <T extends object>(value: any): value is T => | |
isObjectBasicCheck(value) && TO_STRING.call(value) === '[object Object]'; | |
/* | |
function prop<T extends TJSValue>(object: T, key: string) { | |
return object[key]; | |
} | |
*/ | |
/** | |
* array filter function to get the intersection | |
* | |
* @param {T[]} values | |
* @param {string} byObjectProperty | |
* | |
* @return {TFilter<T>} | |
*/ | |
function filterIntersection<T extends TJSValue>(values: T[], byObjectProperty?: string): TArrayFilter<T> { | |
if (byObjectProperty) { | |
return (x: T) => values.some(y => x[byObjectProperty] === y[byObjectProperty]); | |
} | |
return (x: T) => values.includes(x); | |
} | |
/** | |
* array filter function to get the difference | |
* | |
* @param {T[]} values | |
* @param {string} byObjectProperty | |
* | |
* @return {TArrayFilter<T>} | |
*/ | |
function filterDifference<T extends TJSValue>(values: T[], byObjectProperty?: string): TArrayFilter<T> { | |
if (byObjectProperty) { | |
return (x: T) => !values.some(y => x[byObjectProperty] === y[byObjectProperty]); | |
} | |
return (x: T) => !values.includes(x); | |
} | |
// -------------------------------------------------------------------------- // | |
/** | |
* array find function | |
* | |
* @param {T} value | |
* @param {string} byObjectProperty | |
* | |
* @return {TArrayFilter<T>} | |
*/ | |
function filterFindValue<T extends TJSValue>(value: T, byObjectProperty?: string): TArrayFilter<T> { | |
if (byObjectProperty) { | |
return (x: T) => x[byObjectProperty] === (isObject(value) ? value[byObjectProperty] : value); | |
} | |
return (x: T) => x === value; | |
} | |
// -------------------------------------------------------------------------- // | |
/** | |
* from a given array get the unique elements from it | |
* | |
* @param {T[]} values | |
* @param {string} byObjectProperty - optional parameter in case of array of objects | |
* | |
* @return {T[]} values without repetition | |
*/ | |
function unique<T>(values: T[], byObjectProperty?: string): T[] { | |
return values.reduce( | |
(unique, item) => { | |
return filterIntersection(unique, byObjectProperty)(item) ? unique : [...unique, item]; | |
}, | |
[] as T[] | |
); | |
} | |
/** | |
* get only the values present on both parameters arrays | |
* | |
* @param {T[]} arr1 | |
* @param {T[]} arr2 | |
* @param {string} byObjectProperty - optional parameter in case of array of objects | |
* | |
* @return {T[]} values present on both arrays | |
*/ | |
function intersection<T>(arr1: T[], arr2: T[], byObjectProperty?: string): T[] { | |
return arr1.filter(filterIntersection(arr2, byObjectProperty)); | |
} | |
/** | |
* check if the first parameter contains the values from the second parameter | |
* | |
* @param {T[]} sourceArray | |
* @param {T[]} matchArray | |
* @param {string} byObjectProperty - optional parameter in case of array of objects | |
* | |
* @return {boolean} flag | |
*/ | |
function contains<T>(sourceArray: T[], matchArray: T[], byObjectProperty?: string): boolean { | |
const arr2Lenght = matchArray.length; | |
const arr3 = intersection<T>(sourceArray, matchArray, byObjectProperty); | |
return arr2Lenght === arr3.length; | |
} | |
/** | |
* get the different values present on the first parameter | |
* | |
* @param {T[]} sourceArray | |
* @param {T[]} matchArray | |
* @param {string} byObjectProperty - optional parameter in case of array of objects | |
* | |
* @return {T[]} | |
*/ | |
function difference<T>(sourceArray: T[], matchArray: T[], byObjectProperty?: string): T[] { | |
return sourceArray.filter(filterDifference(matchArray, byObjectProperty)); | |
} | |
/** | |
* get the different values present on both parameters arrays | |
* | |
* @param {T[]} arr1 | |
* @param {T[]} arr2 | |
* @param {string} byObjectProperty - optional parameter in case of array of objects | |
* | |
* @return {T[]} | |
*/ | |
function symmetricDifference<T>(arr1: T[], arr2: T[], byObjectProperty?: string): T[] { | |
return arr1 | |
.filter(filterDifference(arr2, byObjectProperty)) | |
.concat(arr2.filter(filterDifference(arr1, byObjectProperty))); | |
} | |
/** | |
* find a value inside of the given values array | |
* | |
* @param {T[]} values | |
* @param {T} value | |
* @param {string} byObjectProperty - optional parameter in case of array of objects | |
* | |
* @return {T | undefined} value founded or undefined | |
*/ | |
function find<T extends TJSValue>(values: T[], value: T, byObjectProperty?: string): T | undefined { | |
return values.find(filterFindValue(value, byObjectProperty)); | |
} | |
/** | |
* Merge two arrays of given type where will return a new array with the values updates | |
* and the new non repeted elements added to it | |
* | |
* @param {T[]} sourceArray | |
* @param {T[]} withArray | |
* @param {string} byObjectProperty - optional parameter in case of array of objects | |
*/ | |
function merge<T>(sourceArray: T[], withArray: T[], byObjectProperty?: string): T[] { | |
if (!byObjectProperty) { | |
return symmetricDifference(sourceArray, withArray); | |
} | |
return [ | |
...sourceArray.map(item => { | |
const element = find(withArray, item, byObjectProperty); | |
if (element) { | |
return element; | |
} | |
return item; | |
}), | |
...difference(withArray, sourceArray, byObjectProperty), | |
]; | |
} | |
// -------------------------------------------------------------------------- // | |
export { | |
unique as arrayUnique, | |
intersection as arrayIntersection, | |
difference as arrayDifference, | |
contains as arrayContains, | |
symmetricDifference as arraySymmetricDifference, | |
find as arrayFind, | |
merge as arrayMerge, | |
}; | |
// -------------------------------------------------------------------------- // | |
export default { | |
unique, | |
intersection, | |
difference, | |
contains, | |
symmetricDifference, | |
find, | |
merge, | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment