12tet
Version:
Music theory library for generating and working with chords, modes, intervals, etc.
150 lines (149 loc) • 5.36 kB
JavaScript
;
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;