Noob help with StringArray and how to loop them


(EDITED - for better reading)

Well this is embarassing! i am learning c++ as i am learning juce so i am quite afraid to use different syntax  other then  

juce kind  of syntax because i don't know how it will reflect on other platforms. Anyway. 


for that reason i created a :

StringArray array1[7][4]; // (between how to startup a StringArray on his creation?)

then added some values  with:

array1.add() // because i couldn't give data like this:  array1[0][0]="1";

 (between is it possible?)


now i want to do use 2 for loops and std::cout the values:

for (int i=0; i<7; i++) // i would like to have the array.size()in the second argument but i don't know how 


   for (int j=0; j<4; j++)  // i would like to have the array[i].size() in the second argument but i don't know how 


       std::cout << array1[i][j];




Am i thinking ok? if so can you gimme some hints how to achiece this? Any help welcome 

thank you



So much StringArray-ception... To start, there's a style for posting code; it would drastically improve a post's readability.

StringArray array1[7][4]; //Like this!

Now, the code above is bringing up questions; what are you trying to achieve with it? StringArray is already an array (as its name implies)... If the goal is to simply contain a list of strings, there's no need in making it multi-dimensional.


A StringArray does not need that kind of initialization you would just do

StringArray collection; in your class 

Then just add elements to it


then just 

for (int i = 0; i < collection.size(); ++i)

   const String item (collection[i]); //here you create a new string called item based on the one in the collection
   DBG(item); //here you should see the output



i will look at that style for code which i wasn't aware of. 

i want to keep information about a chord, for unknown number of chords, like: 

chord[0]["root_note"]="C";  // or note number (still not sure)

chord [0] ["quality"]="minor"

chord [0] ["extensions"]="#9";

in PHP World this would work, but in c++ i have to think in some other way, maybe an array of structs? :| (never did it)

or doing a Chord Class and then an OwnedArray to keep their objects? (is this apperently a better aproach?)


Thank you ;)



well Thank you! the 2 dimension arrays solution is what i was looking for, . but i have learned a few more things 

under your code. Cheers


i want to keep information about a chord, for unknown number of chords, like: 

C++ has a different object model, i think something along this lines would be better in the long term:

Example header:

#if !defined(__Chord_h)
#define __Chord_h
#include "JuceHeader.h"
class Chord  
    Chord ();

    String rootNote; //all this things would be better as objects....
    String quality;
    String extension;



Initialize an owned array of chords:

OwnedArray<Chord> chords;

Create a new Chord and add it to the chords collection:

ScopedPointer<Chord> chord = new Chord();
chord->rootNote = "something";
chord->quality = "something";
chord->extension = "something";

Later you can add getters, setters, define all those other things as other objects, something like:

Chord* chord = chords.getLast();
if (chord != nullptr)
  chord->setRootNote(new RootNote("C")); //¿perhaps rootnote will need to do other stuff? 

Use C++ static type for your benefit, don't see it as a constrain.

And check out the:

There you will learn a lot.



Thanks a lot sambecket! very nice from you!




ScopedPointer<Chord> chord = new Chord(); 

Just curious, why did you use a ScopedPointer and not a normal pointer, which is added to the OwnedArray? The Owned Array keeps track of references so there will be no leaking and first creating the ScopedPointer and then releasing it only 4 lines later makes no sense to me (or did I miss something?)


to be honest i still don't know what ScopedPointer is aimed to, .. but sounds good :P

anyway i am curiose too.


Hi Chris, that's totally correct, i was just trying to show a little RAII, perhaps the initialization is in another function, and then it is added, but mainly i was just trying to be helpful, as per the OP, he is now curious on what a scoped pointer is, and if he starts from now with nice RAII habits, that can only lead to good code with no memory leaks.

In real production code, i will probably create an specific constructor, and then just do c.add(new Something(&params)), or use the raw pointer approach since it will be automatically managed yes




Though contextual, if it were up to me, this simple piece of code

ScopedPointer<Chord> chord = new Chord();
chord->rootNote = "something";
chord->quality = "something";
chord->extension = "something";
chords.add(chord.release()); //assumed OwnedArray<Chord>

Would be this, to avoid the ScopedPointer altogether:

Chord* chord = chords.add (new Chord()); //assumed OwnedArray<Chord>

chord->rootNote = "something";
chord->quality = "something";
chord->extension = "something";

On top of that, the Chord class could be constructed by its 3 members to further simplify, resulting in something like this down the line:

chords.add (new Chord ("rootNote", "quality", "extension"));

To think ahead, I'd avoid using strings for representing a class like this. You could harness the power of enumerations and integers; this would reduce typos, and reduce used memory.


Just an fyi, I'd suggest not doing this, as stated by the juce's ScopedPointer docs:

ScopedPointer<Chord> chord = new Chord();

but doing this instead:

ScopedPointer<Chord> chord (new Chord());




nice. i will defenetly have that in mind! 



Well I didn't want to be picky, but maybe there is a aesthetic reason or common practice to do so, so thanks for clearing this up :)