juce::Array of my struct- use sort, contains & similar methods?

Hello- I currently have a Struct defined as the following-

struct ChordscaleVoice {
    uint16 harmonic = 1;
    bool includedInTrigger = true;
    bool includedInPlayArea = true;
};

In my class Chordscale, I have a juce::Array of these ChordscaleVoice structs. Preferably, I would be able to sort & search the array based on the value of each ChordscaleVoice’s ‘harmonic’.

I am unsure if this is possible with juce::Array. I did notice there is a sort method that uses an ‘ElementComparator’, but I am unsure how to implement such for my ChordscaleVoice struct. In looking into how to do so, I stumbled on this post from jules saying not to do so any longer-

Admittedly I’ve not coded much in many years, having done most of my C++ work as a hobbyist half my life ago, so I’m uncertain how to implement these approaches.

Is there a way I can get juce::Array to behave how I would like it to with structs I create, or perhaps a similar data structure implementation that I could use that does what I want?


One alternative I thought of was eschewing my ChordscaleVoice structs and simply keeping multiple Arrays of fundamental types in my Chordscale that represent it, but I would still need to implement my own sort+swap methods to ensure all the arrays follow the harmonic array, and code bloat will increase with each new parameter a voice has.

I would go with std::vector (since I am more familiar with it). Suppose you have a vector

std::vector<ChordscaleVoice> voices

Then you can pass a comp function to std::sort:

std::sort(voices.begin(), voices.end(), [](const ChordscaleVoice &v1,const ChordscaleVoice &v2) -> bool { return v1.harmonic > v2.harmonic; }); // descending order

For more information about std::sort, see:

https://cplusplus.com/reference/algorithm/sort/

2 Likes

Gave std::vector a go, but since I don’t have the c++ stockholm syndrome I once had, a lot of the syntax & naming of the std library feels really unintuitive to me. I’m sure it’d be better to relearn it, but as a present hobbyist I’d prefer to stick to the more intuitive juce::Array if I can.

Would the following overloads for my struct allow for all the default find & sort based operations in juce::Array to perform as expected?

bool ChordscaleVoice::operator> (const ChordscaleVoice  &v) const {return harmonic >  v.harmonic;}
bool ChordscaleVoice::operator>=(const ChordscaleVoice  &v) const {return harmonic >= v.harmonic;}
bool ChordscaleVoice::operator==(const ChordscaleVoice  &v) const {return harmonic == v.harmonic;}
bool ChordscaleVoice::operator<=(const ChordscaleVoice  &v) const {return harmonic <= v.harmonic;}
bool ChordscaleVoice::operator< (const ChordscaleVoice  &v) const {return harmonic <  v.harmonic;}

bool ChordscaleVoice::operator> (const int   &i) const {return harmonic >  i;}
bool ChordscaleVoice::operator>=(const int   &i) const {return harmonic >= i;}
bool ChordscaleVoice::operator==(const int   &i) const {return harmonic == i;}
bool ChordscaleVoice::operator<=(const int   &i) const {return harmonic <= i;}
bool ChordscaleVoice::operator< (const int   &i) const {return harmonic <  i;}

bool operator> (const int &i, const ChordscaleVoice &v) {return i >  v.harmonic;}
bool operator>=(const int &i, const ChordscaleVoice &v) {return i >= v.harmonic;}
bool operator==(const int &i, const ChordscaleVoice &v) {return i == v.harmonic;}
bool operator<=(const int &i, const ChordscaleVoice &v) {return i <= v.harmonic;}
bool operator< (const int &i, const ChordscaleVoice &v) {return i <  v.harmonic;}

[also, not sure if the comparison to integer overloads are necessary for Array, it’s not something I’ll ever do manually myself]

According to the docs of sort(), the operator<() should be already enough:

This will work for primitive types and objects that implement operator<().

1 Like