Basically, I am wanting to generate arbitrary length string of musical notes, for example from A to G where after G it naturally wraps around to A in another octave. So far, I have this:
function generateNotes($start, $numbers) {
$notes = ['A', 'B', 'C', 'D', 'E', 'F', 'G'];
$indice = array_search($start, $notes);
foreach (range(0, $numbers-1) as $number) {
if(($number + $indice) >= count($notes)) {
$number -= count($notes);
}
echo ($number + $indice) . " ";
}
}
echo generateNotes('E', 24);
What I get is the following, which confuses me:
4 5 6 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
It works the first time, 6 (being G) wrapping around to 0 (A), however the next time (number+indice) > 6 it never works again. Why does it only work the first time within the loop?
Your problem is that you are attempting to assign $number
in the if
block inside the foreach
, but at the end of each loop, the value of $number
is overwritten again by the foreach
, so what you do has no effect. It's easier to just use modulo arithmetic instead:
function generateNotes($start, $numbers) {
$notes = ['A', 'B', 'C', 'D', 'E', 'F', 'G'];
$num_notes = count($notes);
$indice = array_search($start, $notes);
foreach (range(0, $numbers-1) as $number) {
echo (($number + $indice) % $num_notes) . " ";
}
}
echo generateNotes('E', 24);
Output:
4 5 6 0 1 2 3 4 5 6 0 1 2 3 4 5 6 0 1 2 3 4 5 6