Hi,
is it possible to perform a std::sort on a ValueTree?
I got std::find_if to work with a Valuetree, but not std::sort. Is this possible? would be really cool, if not, are there any easy examples for juce::ValueTree::sort ?
Best,
equinox
Hi,
is it possible to perform a std::sort on a ValueTree?
I got std::find_if to work with a Valuetree, but not std::sort. Is this possible? would be really cool, if not, are there any easy examples for juce::ValueTree::sort ?
Best,
equinox
ValueTree features a sort function.
Since ValueTree has begin() and end() iterators I quickly threw a std::sort at it, but the Iterators seemed not to work with std::sort. But could have been my fault)
int main (int argc, char* argv[])
{
juce::ValueTree tree {"Parent", {},
{
{"Node",{{"text", "Ape"}}},
{"Node",{{"text", "Zebra"}}},
{"Node",{{"text", "Elephant"}}}
}};
DBG (tree.toXmlString());
struct Sorter
{
int compareElements (const juce::ValueTree& first, const juce::ValueTree& second)
{
return first.getProperty ("text").toString().compare (second.getProperty ("text").toString());
}
};
Sorter sorter;
tree.sort (sorter, nullptr, false);
// but this didn't compile here:
// std::sort (tree.begin(), tree.end(), [](const auto& first, const auto& second)
// {
// return first.getProperty ("text").toString().compare (second.getProperty ("text").toString());
// });
DBG ("sorted:");
DBG (tree.toXmlString());
return 0;
}
But the sorter approach did the job
std::sort
requires that the iterator type is a ālegacy random-access iteratorā, but ValueTree::Iterator
is only a ālegacy forward iteratorā. Therefore, std::sort
should not be expected to work with ValueTree iterators.
Thanks for the example!
Sorter sorter;
tree.sort (sorter, nullptr, false);
Could also be
tree.sort (Sorter(), nullptr, false);
But still longer than some modern std::sort stuff
Thanks for the info! Ok, is there any chance that the iterator will be updated (if this is possible at all?).
Otherwise it would be also cool, if juce::ValueTree::sort() would just take some lamdba function.
I donāt think we have any plans in this area at the moment.
Ok, sad to hear.
would be really cool if it would be possible to shortn up those ~8 lines above to:
tree.sort([](const juce::ValueTree& first, const juce::ValueTree& second)
{ return first.getProperty("text").toString().compare(second.getProperty("text").toString()); }, nullptr, false);
But anyway Iām glad that there is also a solution right now.
It is possible, with a little helper:
template<typename T>
struct LambdaSorter
{
LambdaSorter (std::function<int(const T&, const T&)> s) : sortFunc (s) {}
int compareElements (const T& first, const T& second)
{
return sortFunc (first, second);
}
private:
std::function<int(const T&, const T&)> sortFunc;
};
int main (int argc, char* argv[])
{
juce::ValueTree tree {"Parent", {},
{
{"Node",{{"text", "Ape"}}},
{"Node",{{"text", "Zebra"}}},
{"Node",{{"text", "Elephant"}}}
}};
LambdaSorter<juce::ValueTree> sorter ([](const auto& first, const auto& second)
{
return first.getProperty ("text").toString().compare (second.getProperty ("text").toString());
});
tree.sort (sorter, nullptr, false);
DBG ("sorted:");
DBG (tree.toXmlString());
return 0;
}
Your idea to build in place doesnāt compile btw, because the ElementComparator is taken by referenceā¦
Since the sort function is bespoke to the ValueTree you might save the hassle of templating as wellā¦
Might be a trivial addition to the ValueTree as well, if the juce team wants to add that
Cool thanks for your help! With your helper I was able to produce a compiling one-liner
Helper:
struct LambdaSorter
{
using Vt = juce::ValueTree;
LambdaSorter(std::function<int(const Vt&, const Vt&)> s) : sortFunc(s) {}
int compareElements(const Vt& a, const Vt& b)
{
return sortFunc(a, b);
}
private:
std::function<int(const Vt&, const Vt&)> sortFunc;
};
Example with one-liner:
juce::ValueTree tree{ "Parent",
{},
{ { "Node", { { "text", "Ape" } } },
{ "Node", { { "text", "Zebra" } } },
{ "Node", { { "text", "Elephant" } } } } };
DBG(tree.toXmlString());
tree.sort(LambdaSorter ([](const auto& first, const auto& second) {
return first.getProperty("text").toString().compare(second.getProperty("text").toString()); }),
nullptr, false);
DBG("sorted:");
DBG(tree.toXmlString());
The Sorted()
compiled also on my machine
I just cleaned it up a bit and send it to JUCE:
Letās see where it ends up
cool!
Little bump, now that the ADC dust has settledā¦