| 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;
})
);
}, []);
};
|