Ruby Exercise
Posted: Tue Apr 11, 2017 12:22 pm
So.... I needed a Hash where note numbers are the keys and note names are the values, so instead of typing it all out I thought it would be a good exercise to try and auto-generate it.

So whilst what I've come up with does actually work, I can't help thinking that there must be a more elegant, Ruby way of doing this.
Would any of the Ruby experts on here care to take a look and show me how it should be done?
Thanks in advance
Dave

Code: Select all
# 1 - Generate note names, we need to start with C so doing it in 2 steps:
a = ((Array("C".."G") + Array("A".."B")).zip Array("C#".."G#") + Array("A#".."B#")).flatten
# 2 - Remove the B# and E#:
a.delete_if{|e|e == "B#"||e =="E#"} # gives: ["C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"]
# 3 - Repeat a 11 times:
b = Array.new(11,a).flatten
# 4 - Generate 0 to 10 (the octave nos) 12 times and sort:
c =((Array (0..10)) * 12).sort # Gives: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1,... 10, 10]
# 5 - Zip b and c together and remove the last 4 elements:
d = b.zip(c).take(128) # Gives: [["C", 0], ["C#", 0], ["D", 0], ["D#", 0], ["E", 0]..... ["F#", 10], ["G", 10]]
# 6 - Join the note names and octave nos together:
e = d.map{|e|e[0] + e[1].to_s} # Gives: ["C0", "C#0", "D0", "D#0",...... "F#10", "G10"]
# 7 - Generate the Hash
notes = Hash[e.map.with_index{ |x, i| [i, x ] }] # Gives: {0=>"C0", 1=>"C#0",..... 126=>"F#10", 127=>"G10"}
watch notesSo whilst what I've come up with does actually work, I can't help thinking that there must be a more elegant, Ruby way of doing this.
Would any of the Ruby experts on here care to take a look and show me how it should be done?
Thanks in advance
Dave