UNPKG

@allmaps/stdlib

Version:

Allmaps Standard Library

142 lines (141 loc) 4.64 kB
import { differenceWith, fromPairs, toPairs, isEqual, cloneDeep, pick } from 'lodash-es'; export function degreesToRadians(degrees) { return degrees * (Math.PI / 180); } export function radiansToDegrees(radians) { return radians * (180 / Math.PI); } export function angle(line) { return Math.atan2(line[1][1] - line[0][1], line[1][0] - line[0][0]); } export function bearing(line) { return angle(line) - Math.PI / 2; } // Define vanilla groupBy function, since official one is only baseline 2024 // See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/groupBy // Vanilla code from https://stackoverflow.com/a/62765924/2386673 // eslint-disable-next-line @typescript-eslint/no-explicit-any export function groupBy(arr, key) { return arr.reduce((groups, item) => { ; (groups[key(item)] ||= []).push(item); return groups; }, {}); } // Note: this checks equality of the object // which is only a good idea for primitive types (string, number), not JSON objects export function isEqualArray(array0, array1, isEqualObject = (t0, t1) => t0 == t1) { if (array0.length !== array1.length) { return false; } for (let i = 0; i < array0.length; i++) { if (!isEqualObject(array0[i], array1[i])) { return false; } } return true; } // Returns objects in array0 that are not in array1 export function arrayDifference(array0, array1, isEqualObject = (t0, t1) => t0 == t1) { const result = []; for (let i = 0; i < array0.length; i++) { let found = false; for (let j = 0; j < array1.length; j++) { if (isEqualObject(array0[i], array1[j])) { found = true; break; } } if (!found) { result.push(array0[i]); } } return result; } export function arrayUnique(array, isEqualObject = (t0, t1) => t0 == t1) { const result = []; for (let i = 0; i < array.length; i++) { let found = false; for (let j = 0; j < i; j++) { if (isEqualObject(array[i], array[j])) { found = true; break; } } if (!found) { result.push(array[i]); } } return result; } export function arrayRepeated(array, isEqualObject = (t0, t1) => t0 == t1) { const result = []; for (let i = 0; i < array.length; i++) { let found = false; for (let j = 0; j < i; j++) { if (isEqualObject(array[i], array[j])) { found = true; break; } } if (found) { result.push(array[i]); } } return result; } // TODO: replace with Set subset once available // Note: this checks equality of the object // which is only a good idea for primitive types (string, number), not JSON objects export function subSetArray(arr1, arr2) { for (let i = 0; i < arr2.length; i++) { if (arr1.indexOf(arr2[i]) === -1) { return false; } } return true; } // TODO: Replace with Set equality once available // Note: this checks equality of the object // which is only a good idea for primitive types (string, number), not JSON objects export function equalSet(set1, set2) { if (!set1 || !set2) { return false; } if (set1.size !== set2.size) { return false; } return [...set1].every((x) => set2.has(x)); } // From https://gist.github.com/Yimiprod/7ee176597fef230d1451 export function objectDifference(newObject, baseObject) { return fromPairs(differenceWith(toPairs(newObject), toPairs(baseObject), isEqual)); } export function objectOmitDifference(newObject, baseObject) { const keysToOmit = Object.keys(objectDifference(newObject, baseObject)); return pick(newObject, keysToOmit); } // Basic omit function as replacement for lodash omit, since it will be removed in v5 // See: https://github.com/lodash/lodash/issues/2930#issuecomment-272298477 // eslint-disable-next-line @typescript-eslint/no-explicit-any export function omit(object, keys) { const result = cloneDeep(object); for (const key of keys) { delete result[key]; } return result; } export function isValidHttpUrl(string) { let url; try { url = new URL(string); } catch (_) { return false; } return url.protocol === 'http:' || url.protocol === 'https:'; } export function camelCaseToWords(string) { const result = string.replace(/([A-Z])/g, ' $1'); return result.charAt(0).toUpperCase() + result.slice(1); }