Am I Missing Something? Getting Length of Array

So, I have a list of arrays, and I want to loop through the list of arrays, and send a array into the method, and sleep for the amount of notes in the array I’m sending in.

I have been looking for documentation on it, and I can’t find it. The RubyDocs page I found on the array doesn’t have size or length or count that I can find.

I found a workaround where I loop through and count on a variable, then use that, but there has to be a better way. I’m doing this to refactor code, and though I made it modular, I didn’t exactly shrink my code line count at all, so I want a more elegant solution if possible.

Can someone point me in the direction of some documentation?

Edit: Since most of them in the sequence are 2, 3, or 4, I’m going to hardcode them for now, but I would like to figure out how to get the count dynamically still if possible.

Hi Skelly…

I’m no array-mechanic but something like?

Eli…

flute = [ 76, 74, 80, 76, 76, 80, 74, 78]
puts flute.length
1 Like

I must just be having a bad morning. :rofl:

I haven’t really done much with arrays since most of my stuff has just been samples so far, or long single notes.

For the life of me, I could not find a reference to that method anywhere when I was looking for it…

Oh well. Now I know.

#ThereAreNoStupidQuestions

If I had a penny for every silly question I’ve ask on this
forum… Sam wouldn’t need a patreon, I’d be funding him
outright. :slight_smile:

Glad to help.

Eli.

1 Like

Thanks again.

I’ll post the thing I’m refactoring when It’s done.

It was in a state where a normie would look at it and go “OH WOW COOL!!! :D” but you guys would notice how much line space I’m wasting. :joy:

That’s what you get for trying to build and compose at the same time.

No shame in using a lot of lines to do a thing. It’s better to use a few more lines and make something comprehensible, that to refactor all the meaning out of your code in an effort to save space.

2 Likes

Hi there,

I’m always using more lines of code than really needed, because it is easier that way to change and reuse stuff than with compact forms.
So, no problem in there.

Cu.

If you haven’t found the answer yet, I just came across the same issues. It’s rather simple…

myArray = [ 1, 2, 3, 4, 5, 6]

myArray.count returns 6 as the number of items inside the array

Does it work for rings, too?

If you create an array first…

notes = [36 , 42 , 36 , 30]

then use .ring to play through the list…

notes.ring

you have your ring of notes. You can now get the count with…

notes.count

which will return 4 as the count

You can now get the count with…

notes.count

@tvolikas/@Loopiloop - unless I’m missing something, unfortunately not.
Running the following:

puts [36 , 42 , 36 , 30].ring.count

Produces the following error:

Runtime Error: [buffer 9, line 1] - NoMethodError
Thread death!
 undefined method `count' for (ring 36, 42, 36, 30):SonicPi::Core::RingVector

Technically speaking, .length and .size both work, for rings and arrays, so you may use those with either instead.

It’s worth keeping in mind however that functions such as .length, .size, .count etc are not part of the officially supported Sonic Pi language, and are not guaranteed to continue working into the future.

I am planning to update the documentation some time in the not too distant future to hopefully make the difference between Sonic Pi language and that of Ruby (that the Sonic Pi language is based on) clearer, to try to avoid any confusion.

1 Like

Ooof… I hope Sonic Pi doesn’t lose the ability to get the count of an array.

Is there any reason why .count wouldn’t remain in Sonic Pi?

There is a possibility, however delayed, that one day the Sonic Pi language may be rewritten in another base language altogether.
A key point to keep in mind is that we would give plenty of notice about such a thing.

The comments on the replies to the following topic may be useful:

Hi ethan and everyone, I went down the rabbit hole yesterday whilst reviewing online resources. I learned a lot (the tutorial is AMAZING :star::star::star::star::star:) but I couldn’t complete my first task of retrieving notes from passed scale name - some bad symbol parsing.

First iterating over the scales presents no issue

for s in 0..(scale_names.length-1)
  current_scale = scale_names[s]
  puts "playing scale pattern #{current_scale}"

outputs the following (NB the leading ‘:’ is omitted from name)

playing scale pattern acemli_rast

when hard-coded with the scale name as a parameter the command works

play_pattern_timed scale(:major), 0.125

but when trying to pass the scale name (eg ‘:major’) accessed as an array identifier
play_pattern_timed scale (scale_names[s]), 0.125

an error is returned

undefined method `to_sym’ for 0.125:Float

When evaluating the length of the scale name, it appears to be absent the leading :

puts "scale name length = #{current_scale.length}"

“scale name length = 11”

but it seems you’re unable to concat
pattern_name = ':' + (current_scale)

no implicit conversion of Symbol into String

:question: Is it possible to repeat over the names of the scales, and access the current name, and pass this as a parameter to play_pattern_timed scale ?

Bing GPT for the win!

After a couple of passes I’ve learned

  • the leading ‘:’ is not required
  • the .to_s and .to_sym functions can be used to convert
  • the recommended eval function is not required (and does not work)

Syntactically all is good with just occasional warnings about late notes, but no sound coming out, so back to drawing board (tutorials:) to check the function, and a low release seems to help… adding these in still yielded no beeps, so

  • I added some debug output, to test the pattern calls in a separate buffer
    • syntax is good, but also nothing out, so set the tonic to :C3… :boom:

I’ll add these optional/default parameters then ready for next playtime and tidy up…

sharing here, any suggestions etc > welcome :sunglasses:

In case it helps others, here’s the steps - I’ll share a link once refactored into a useful function / tutorial

:warning: the output sounds don’t sound as different as I expect per scale, so I’m not entirely sure it’s doing exactly what I thought!

#init
r = 0.1
tonic = 48

#### For each scale s in Scale Patterns
for s in 0..(scale_names.length-1)
  current_scale = scale_names[s]
  
  #DEBUG msg
  puts "play_pattern_timed scale(tonic,#{current_scale.to_sym}), 0.125, release: 0.1"
  
  play_pattern_timed scale(tonic, current_scale.to_sym), 0.125, release: r
  sleep 1
  
end

I would usually use this for iterating over scale names

use_debug false
use_synth :tri
scale_names.each do |n| #n will contain the current scale name
  snotes=scale(:c4, n) #tonic :c4
  play_pattern_timed snotes,0.125,release: 0.125
end

EDIT you can do something similar for sample_groups and sample_names eg

sample_groups.each do |g|
  sample_names(g).each do |s|
    puts s
    #sample s
    #sleep sample_duration(s)
  end
end

You can uncomment the two lines in the middle to play them, but it will take quite a long time to complete