1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 | 1x 1x 3x 3x 4x 1x 1x 1x 1x 29x 1x 56x 56x 28x 7x 1x 1x 1x 4x 4x 4x 4x 1x 1x 4x 3x 4x 9x 9x 9x | import { midi, name } from "tonal-note"; // ascending range function ascR(b, n) { for (var a = []; n--; a[n] = n + b); return a; } // descending range function descR(b, n) { for (var a = []; n--; a[n] = b - n); return a; } /** * Create a numeric range * @param {Number} from * @param {Number} to * @return {Array} * @example * array.range(-2, 2) // => [-2, -1, 0, 1, 2] * array.range(2, -2) // => [2, 1, 0, -1, -2] */ export function range(a, b) { return a === null || b === null ? [] : a < b ? ascR(a, b - a + 1) : descR(a, a - b + 1); } /** * Rotates a list a number of times. It's completly agnostic about the * contents of the list. * @param {Integer} times - the number of rotations * @param {Array} array * @return {Array} the rotated array */ export const rotate = (times, arr) => { var len = arr.length; var n = (times % len + len) % len; return arr.slice(n, len).concat(arr.slice(0, n)); }; /** * Return a copy of the array with the null values removed * @param {Array} array * @return {Array} * @example * tonal.compact(['a', 'b', null, 'c']) // => ['a', 'b', 'c'] */ export const compact = arr => arr.filter(n => n === 0 || n); // a function that get note heights (with negative number for pitch classes) const height = n => { const m = midi(n); return m !== null ? m : midi(n + "-100"); }; /** * Sort an array of notes in ascending order * * @private * @param {String|Array} notes * @return {Array} sorted array of notes */ export function sort(src) { return compact(src.map(name)).sort((a, b) => height(a) > height(b)); } /** * Get sorted notes with duplicates removed * * @private * @function * @param {Array} notes */ export function unique(arr) { return sort(arr).filter((n, i, a) => i === 0 || n !== a[i - 1]); } /** * Randomizes the order of the specified array in-place, using the Fisher–Yates shuffle. * * @private * @function * @param {Array|String} arr - the array * @return {Array} the shuffled array * * @example * import * as array from 'tonal-array' * array.shuffle(["C", "D", "E", "F"]) */ export var shuffle = (arr, rnd = Math.random) => { var i, t; var m = arr.length; while (m) { i = (rnd() * m--) | 0; t = arr[m]; arr[m] = arr[i]; arr[i] = t; } return arr; }; /** * Get all permutations of a list * http://stackoverflow.com/questions/9960908/permutations-in-javascript * * @param {Array|Strng} list - the list * @return {Array<Array>} an array with all the permutations */ export const permutations = arr => { if (arr.length === 0) return [[]]; return permutations(arr.slice(1)).reduce(function(acc, perm) { return acc.concat( arr.map(function(e, pos) { var newPerm = perm.slice(); newPerm.splice(pos, 0, arr[0]); return newPerm; }) ); }, []); }; |