UNPKG

12tet

Version:

Music theory library for generating and working with chords, modes, intervals, etc.

150 lines (149 loc) 5.36 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.generateOrderedCombinations = exports.getEvenNumbers = exports.getEvenArrayElements = exports.arrayDifference = exports.getTypedObjectKeys = exports.removeArrayElement = exports.getWrappedArrayElement = exports.isTypeError = exports.wrapValue = exports.sumTo = exports.getShallowCopy = exports.removeDuplicates = exports.rotateArray = void 0; // rotateArray moves array elements forward or backward by the offset amount function rotateArray(array, offset) { const arrayCopy = getShallowCopy(array); // Wrap around the array if the offset is larger or negative // This will prevent shift from ever causing an error if (offset > arrayCopy.length) { offset = offset % arrayCopy.length; } else if (offset < 0) { offset = arrayCopy.length - (Math.abs(offset) % arrayCopy.length); } for (let i = 0; i < offset; i++) { const shift = arrayCopy.shift(); if (shift !== undefined) { arrayCopy.push(shift); } } return arrayCopy; } exports.rotateArray = rotateArray; // Filter out duplicate values from an array // Accepts multi-dimensional arrays function removeDuplicates(array) { if (array.length === 0) { return array; } else if (Array.isArray(array[0])) { const stringArray = array.map(element => JSON.stringify(element)); const uniqueStringArray = new Set(stringArray); return Array.from(uniqueStringArray, element => JSON.parse(element)); } else { return [...new Set(array)]; } } exports.removeDuplicates = removeDuplicates; // Shallow copy an array function getShallowCopy(array) { return array.slice(); } exports.getShallowCopy = getShallowCopy; // Sum array elements up to a given index function sumTo(array, index) { let sum = 0; for (let i = 0; i <= index; i++) { sum += array[i % array.length]; } return sum; } exports.sumTo = sumTo; // Wrap number inside 0 and a max number // i.e. wrapValue(5, 12) === 5 // wrapValue(17, 12) === 5 // wrapValue(-2, 12) === 10 // wrapValue(-14, 12) === 10 function wrapValue(value, max) { const multiples = Math.abs(Math.floor(value / max)) * max; return ((multiples * max) + value) % max; } exports.wrapValue = wrapValue; // Type guard for TypeError function isTypeError(error) { return error instanceof TypeError; } exports.isTypeError = isTypeError; // Get array element at index. Wraps around array if index is greater than the array size or negative function getWrappedArrayElement(array, index) { return array[wrapValue(index, array.length)]; } exports.getWrappedArrayElement = getWrappedArrayElement; function removeArrayElement(array, index) { const arrayCopy = getShallowCopy(array); // If the index is negative, count from the end of the array const effectiveIndex = index < 0 ? arrayCopy.length - Math.abs(index) : index; if (effectiveIndex >= array.length || effectiveIndex < 0) { console.error(`There was a problem calling removeArrayElement. Effective index ${effectiveIndex} is out of bounds for array with length ${array.length}. Returning array unchanged.`); } else { arrayCopy.splice(effectiveIndex, 1); } return arrayCopy; } exports.removeArrayElement = removeArrayElement; // https://stackoverflow.com/questions/52856496/typescript-object-keys-return-string exports.getTypedObjectKeys = Object.keys; function arrayDifference(array1, array2) { return array1.filter((v) => !array2.includes(v)); } exports.arrayDifference = arrayDifference; function getEvenArrayElements(array) { const elements = []; array.forEach((element, index) => { if (index % 2 === 0) { elements.push(element); } }); return elements; } exports.getEvenArrayElements = getEvenArrayElements; function getEvenNumbers(max) { if (typeof max === 'string') { max = parseInt(max); } const numbers = []; if (max >= 0) { for (let i = 0; i <= max; i++) { if (i % 2 === 0) { numbers.push(i); } } } else { for (let i = 0; i >= max; i--) { if (i % 2 === 0) { numbers.push(i); } } } return numbers; } exports.getEvenNumbers = getEvenNumbers; function indexesOf(array, value) { const indexes = []; for (let i = 0; i < array.length; i++) { if (array[i] === value) { indexes.push(i); } } return indexes; } function generateOrderedCombinations(array, result, combinationSize = array.length - 1) { // Protect you from yourself if (Math.abs(array.length - combinationSize) > 9) { console.error(`You are attempting to generate too many ordered combinations of size ${combinationSize} from an array of length ${array.length}. Try reducing the array length or pickSize`); return; } if (array.length === combinationSize) { result.push(array); } else if (array.length > combinationSize) { for (let i = 0; i < array.length; i++) { generateOrderedCombinations(removeArrayElement(array, i), result, combinationSize); } } } exports.generateOrderedCombinations = generateOrderedCombinations;