Skip to content

Instantly share code, notes, and snippets.

@adamski
Last active November 5, 2019 14:36
Show Gist options
  • Save adamski/8d1c2719bcf0827b44a4 to your computer and use it in GitHub Desktop.
Save adamski/8d1c2719bcf0827b44a4 to your computer and use it in GitHub Desktop.
Binary Search functions for JUCE ValueTree and Array types
/*
==============================================================================
BinarySearch.h
Created: 31 Jul 2014 9:57:04am
Author: Adam Wilson
==============================================================================
*/
#ifndef BINARYSEARCH_H_INCLUDED
#define BINARYSEARCH_H_INCLUDED
#include "../JuceLibraryCode/JuceHeader.h"
#include <typeinfo>
//==============================================================================
class BinarySearch
{
public:
/*
* Binary search algorithm adapted for searching a ValueTree's children for a property matching a given var.
* Will return the closest match if exact match not found.
* User still has to check whether value of index+1 is closer than the returned index.
*/
template <typename Type> static int binarySearch (const ValueTree &searchTree, var key, Identifier propertyName, int start=-1)
{
if (searchTree.isValid())
{
jassert (searchTree.getNumChildren() > 0);
int low, high, med;
ValueTree temp;
high = searchTree.getNumChildren();
low = 0;
// use given start position else work out mid point
med = (start < 0 ? (high + low) / 2 : start);
while (high != low+1)
{
temp = searchTree.getChild (med);
if (!temp.isValid())
{
DBG ("searchTree.getChild (" << med << ") == invalid: reset to " << (high + low) / 2);
med = (high + low) / 2;
continue;
}
if (key == temp[propertyName])
{
return med;
}
else if (static_cast<Type>(temp[propertyName]) < static_cast<Type>(key))
{
low = med;
}
else
{
high = med;
}
med = (high + low) / 2;
}
return med;
}
return -1;
}
/** Binary Search for JUCE Array type
*/
template <typename Type> static int binarySearch (const Array <Type> &searchArray, Type value, int start=-1)
{
int low, high, med;
high = searchArray.size();
low = 0;
Type temp;
// use given start position else work out mid point
med = (start < 0 ? (high + low) / 2 : start);
//DBG ( "med: "+String(med) + ", high: " + String(high) +", low: " + String(low));
String debug;
while (high != low+1)
{
temp = searchArray.getUnchecked (med);
DBG ("if (" + String(value) + " == " + String(temp) + ")");
if (value == temp)
{
return med;
}
else if (temp < value)
{
low = med;
}
else
{
high = med;
}
med = (high + low) / 2;
debug << String (med) << ": (" << String (high) << "," << String (low) << ")[" << String (temp) << "], ";
}
DBG (debug);
return med;
}
};
#endif // BINARYSEARCH_H_INCLUDED
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment