#ifndef UDO_ARRAYTOOLS #define UDO_ARRAYTOOLS ## /* Array tools This file is part of the SONICS UDO collection by Richard Knight 2021 License: GPL-2.0-or-later http://1bpm.net */ giassocarrayvalues[] init 1 gSassocarraykeys[] init 1 /* Get a random value from an array ivalue arr_random iarray[] kvalue arr_random iarray[] Svalue arr_random Sarray[] ivalue selected value kvalue selected value iarray[] array to evaluate Sarray[] string array to evaluate */ opcode arr_random, i, i[] iarray[] xin ivalue = iarray[round(random(0, lenarray(iarray) - 1))] xout ivalue endop opcode arr_random, S, S[] Sarray[] xin Svalue = Sarray[round(random(0, lenarray(Sarray) - 1))] xout Svalue endop opcode arr_random, k, i[] iarray[] xin kvalue = iarray[round:k(random:k(0, lenarray(iarray) - 1))] xout kvalue endop /* Append to global associative array */ opcode asarr_append, 0, Si Skey, ivalue xin index = 0 ilen = lenarray(giassocarrayvalues) Snewkeys[] init (ilen + 1) inewvals[] init (ilen + 1) while (index < ilen) do Snewkeys[index] = gSassocarraykeys[index] inewvals[index] = giassocarrayvalues[index] index += 1 od Snewkeys[index] = Skey inewvals[index] = ivalue giassocarrayvalues = inewvals gSassocarraykeys = Snewkeys endop opcode asarr_get, i, S Skey xin index = 0 ivalue = -1 ilen = lenarray(giassocarrayvalues) while (index < ilen) do isame strcmp Skey, gSassocarraykeys[index] if (isame == 0) then ivalue = giassocarrayvalues[index] goto output endif index += 1 od output: xout ivalue endop /* Get the nearest value to kvalue in the one-dimensional array iarray, which should be sorted knearest nearest iarray, kvalue knearest the nearest value found */ opcode arr_nearest, k, i[]k iarray[], kvalue xin knearest = 0 kindex = 0 while (kindex < lenarray(iarray)) do ktest = iarray[kindex] if (abs(kvalue - ktest) < abs(kvalue - knearest)) then knearest = ktest endif kindex += 1 od xout knearest endop ; Snew[] arrayappend Sarray, Svalue ; extend a S array with a given value opcode arr_append, S[], S[]S Sarray[], Svalue xin index = 0 ilen = lenarray(Sarray) Snew[] init (ilen + 1) while (index < ilen) do Snew[index] = Sarray[index] index += 1 od Snew[index] = Svalue xout Snew endop ; inew[] arrayappend iarray, ivalue ; extend an i array with a given value opcode arr_append, i[], i[]i iarray[], ivalue xin index = 0 ilen = lenarray(iarray) inew[] init (ilen + 1) while (index < ilen) do inew[index] = iarray[index] index += 1 od inew[index] = ivalue xout inew endop ; array, asfloat opcode arr_serialise, S, i[]p iarray[], iasfloat xin ilen = lenarray(iarray) index = 0 SprintfChar = (iasfloat == 1) ? "%f" : "%d" Sout = "[" while (index < ilen) do if (index != 0) then Sout = strcat(Sout, ",") endif Sout = strcat(Sout, sprintf(SprintfChar, iarray[index])) index += 1 od Sout = strcat(Sout, "]") xout Sout endop ; array opcode arr_serialise, S, S[] Sarray[] xin ilen = lenarray(Sarray) index = 0 Sout = "[" while (index < ilen) do if (index != 0) then Sout = strcat(Sout, ",") endif Sout = strcat(Sout, sprintf("\"%s\"", Sarray[index])) index += 1 od Sout = strcat(Sout, "]") xout Sout endop opcode arr_unserialise, S[], S Sdata xin ilen = strlen(Sdata) ichar = 0 inarray = 0 instring = 0 iitems = 0 while (ichar < ilen) do Schar = strsub(Sdata, ichar, ichar + 1) if (instring == 0 && strcmp(Schar, "[") == 0) then inarray = 1 elseif (inarray == 1 && instring == 0 && strcmp(Schar, "]") == 0) then inarray = 0 elseif (inarray == 1 && instring == 0 && strcmp(Schar, ",") == 0) then iitems += 1 elseif (inarray == 1 && strcmp(Schar, "\"") == 0) then instring = 1 - instring endif ichar += 1 od Sarray[] init iitems + 1 ichar = 0 inarray = 0 instring = 0 istringstart = -1 index = 0 while (ichar < ilen) do Schar = strsub(Sdata, ichar, ichar + 1) if (instring == 0 && strcmp(Schar, "[") == 0) then inarray = 1 elseif (inarray == 1 && instring == 0 && strcmp(Schar, "]") == 0) then inarray = 0 elseif (inarray == 1 && instring == 0 && strcmp(Schar, ",") == 0) then index += 1 elseif (inarray == 1 && strcmp(Schar, "\"") == 0) then if (instring == 0) then instring = 1 istringstart = ichar + 1 else instring = 0 Sarray[index] = strsub(Sdata, istringstart, ichar) istringstart = -1 endif endif ichar += 1 od xout Sarray endop #end