@allmaps/stdlib
Version:
Allmaps Standard Library
142 lines (141 loc) • 4.64 kB
JavaScript
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);
}